diff --git a/AUTHORS b/AUTHORS
index 47202961..a68e49b9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -270,6 +270,7 @@
 Darshini KN <kn.darshini@samsung.com>
 Dave Vandyke <kzar@kzar.co.uk>
 David Benjamin <davidben@mit.edu>
+David Brown <develop.david.brown@gmail.com>
 David Davidovic <david@davidovic.io>
 David Erceg <erceg.david@gmail.com>
 David Fox <david@davidjfox.com>
diff --git a/DEPS b/DEPS
index 8d6e076..9449a45 100644
--- a/DEPS
+++ b/DEPS
@@ -275,7 +275,7 @@
   # 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': '4d7d29c99f76baac4c26931197260b3ef433fe71',
+  'skia_revision': '37e7856fe65c982e17e9e87f5c91a4fc9ec8d1ab',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -283,11 +283,11 @@
   # 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': '611f0e0d85456f64f176482ba13670a6f807d871',
+  'angle_revision': '28c59d63459abafba42c00a69ff8d1276e6e9655',
   # 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': '26243894edb812abe0f120ac36c400439848dacb',
+  'swiftshader_revision': 'f54df11f323e8734f65f30b5109c42260ec504f4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -390,7 +390,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': 'f5bde5fffcf7280f351bb3bcafc80419166065ed',
+  'dawn_revision': '33fe68ee0f1f2f38caba1f74f44aaeab5892183b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -852,7 +852,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'dyi4_0SKSmwftqg3drQaYWNFSxKO2-2bLabLpevpnX8C',
+          'version': 'qtU6--2RR1JpwjJp40-Rm2osWsJ5dN6OHhn9jAWGOjYC',
         },
       ],
       'dep_type': 'cipd',
@@ -863,7 +863,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'gz7TOW1hqJ1Px4Dgw2Nd4AYP-fh5MpBi-j6hlK0i7ikC',
+          'version': '9Ng_rvcAlM71bKzykN7li3a4z83uE-vFFZabQREyeXkC',
         },
       ],
       'dep_type': 'cipd',
@@ -920,7 +920,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'ERWgY8-3IoHVfwaU-EUbIo2oFOGy_eD6cyer8RFNycIC',
+          'version': '1dbbIJAigC5vXXm9sjPZ4E8jBsVOvIG2Oa4nzMxILCYC',
       },
     ],
     'condition': 'checkout_android',
@@ -1113,7 +1113,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' + '@' + 'ca90875ae1939f5fca571fe474bcb6c0f4abd656',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '071eeb6c55dd3034dcdd546152471a6eb58a4ecc',
       'condition': 'checkout_chromeos',
   },
 
@@ -1516,7 +1516,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '853f7de05f76e7c531e61f414291863a1bbd5ffa',
+    Var('chromium_git') + '/openscreen' + '@' + '87ef25a4154829c4c0450ab4201f40d27508d944',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1533,7 +1533,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6e4908679c0e807b51186ab313f7fade72335aba',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '03b8dd28776e2302fc80953b5df0d0d4424f670c',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1781,7 +1781,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4c9a94f8dc7deb1c5ecfa2dc9a895f94a1befcac',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4e81f8b94aecf15d5cfa72b40e1504004fd18fe1',
     'condition': 'checkout_src_internal',
   },
 
@@ -1811,7 +1811,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'XY3amnchFvokdx8wXOUS0KW6rIQDjnr28NMCytkndRYC',
+        'version': 'Do0A-bPpxUoGJYAokKHpVI_JkyPVBOCFRTtIp4zjymwC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1822,7 +1822,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'Rv69A1PH-Q5kuEN3r2z9ojlMqKs8nX68iWLLJgWHT4gC',
+        'version': '-5XdSXRdc2ECmKOLNEXUtLCQJ19Bf9swwFvMaGS2AV8C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4222,16 +4222,6 @@
     ],
   },
 
-  # Download telemetry_gpu_integration_test binary dependencies
-  {
-    'name': 'checkout_telemetry_gpu_integration_test_binary_dependencies',
-    'condition': 'host_os == "linux"',
-    'pattern': '.',
-    'action': [ 'python3',
-                'src/content/test/gpu/gpu_tests/fetch_gpu_integration_test_dependencies.py',
-    ],
-  },
-
   # Download test data for Maps telemetry_gpu_integration_test.
   {
     'name': 'maps_perf_test_load_dataset',
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index f37fef62..15966e2 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -336,6 +336,8 @@
                             + " scanner."),
             Flag.baseFeature(BaseFeatures.RUN_TASKS_BY_BATCHES,
                     "Run tasks in queue for 8ms before before sending a system message."),
+            Flag.baseFeature(BlinkFeatures.OFFSET_PARENT_NEW_SPEC_BEHAVIOR,
+                    "Enables new HTMLElement.offsetParent behavior to match other browsers."),
             // Add new commandline switches and features above. The final entry should have a
             // trailing comma for cleaner diffs.
     };
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index d7c0769..d88c623 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -2237,8 +2237,7 @@
     "//chromeos/dbus",
     "//chromeos/dbus/audio",
     "//chromeos/dbus/constants",
-    "//chromeos/dbus/hermes:hermes_clients",
-    "//chromeos/dbus/hermes:hermes_fakes",
+    "//chromeos/dbus/hermes",
     "//chromeos/dbus/human_presence",
     "//chromeos/dbus/human_presence:hps_proto",
     "//chromeos/dbus/init",
@@ -3030,8 +3029,7 @@
     "//chromeos/constants",
     "//chromeos/dbus:test_support",
     "//chromeos/dbus/audio",
-    "//chromeos/dbus/hermes:hermes_clients",
-    "//chromeos/dbus/hermes:hermes_fakes",
+    "//chromeos/dbus/hermes",
     "//chromeos/dbus/human_presence",
     "//chromeos/dbus/human_presence:hps_proto",
     "//chromeos/dbus/power",
diff --git a/ash/ambient/COMMON_METADATA b/ash/ambient/COMMON_METADATA
new file mode 100644
index 0000000..da3499a6
--- /dev/null
+++ b/ash/ambient/COMMON_METADATA
@@ -0,0 +1,4 @@
+buganizer {
+  # ChromeOS > Software > Personalization > Ambient Mode
+  component_id: 669199
+}
diff --git a/ash/ambient/DIR_METADATA b/ash/ambient/DIR_METADATA
index 5cf9e51..e8a674f9 100644
--- a/ash/ambient/DIR_METADATA
+++ b/ash/ambient/DIR_METADATA
@@ -1,3 +1 @@
-monorail {
-  component: "UI>Shell>Assistant"
-}
+mixins: "//ash/ambient/COMMON_METADATA"
diff --git a/ash/ambient/model/ambient_animation_photo_provider.cc b/ash/ambient/model/ambient_animation_photo_provider.cc
index 3b7f8a1..6977f57 100644
--- a/ash/ambient/model/ambient_animation_photo_provider.cc
+++ b/ash/ambient/model/ambient_animation_photo_provider.cc
@@ -63,6 +63,7 @@
 
 #include "ash/ambient/resources/ambient_animation_static_resources.h"
 #include "ash/ambient/util/ambient_util.h"
+#include "ash/public/cpp/ambient/ambient_metrics.h"
 #include "ash/utility/cropping_util.h"
 #include "ash/utility/lottie_util.h"
 #include "base/bind.h"
@@ -105,6 +106,11 @@
   };
 }
 
+bool IsPortrait(const gfx::Size& size) {
+  DCHECK(!size.IsEmpty());
+  return size.height() > size.width();
+}
+
 // Provides images for dynamic assets based on the following UX requirements:
 // * Make a best effort to assign portrait images to portrait assets and same
 //   for landscape.
@@ -162,12 +168,6 @@
     // 0 when all topics from all TopicSets have been exhausted.
     size_t current_topic_idx = 0;
   };
-
-  static bool IsPortrait(const gfx::Size& size) {
-    DCHECK(!size.IsEmpty());
-    return size.height() > size.width();
-  }
-
   static const PhotoWithDetails* GetNextTopicFromTopicSet(TopicSet& topic_set) {
     if (topic_set.current_topic_idx >= topic_set.topics.size())
       return nullptr;
@@ -466,6 +466,7 @@
     }
   }
   NotifyObserverOfNewTopics();
+  RecordDynamicAssetMetrics();
   topic_for_target_asset = ExtractPendingTopicForDynamicAsset(target_asset);
   DCHECK(!topic_for_target_asset.photo.isNull())
       << "GenerateNextTopicForDynamicAsset() for unknown asset "
@@ -542,4 +543,33 @@
   }
 }
 
+void AmbientAnimationPhotoProvider::RecordDynamicAssetMetrics() {
+  DCHECK_EQ(pending_dynamic_asset_topics_.size(), total_num_dynamic_assets_)
+      << "RecordDynamicAssetMetrics() must be called when a new topic has been "
+         "assigned to each dynamic asset in the animation";
+  int num_photo_orientation_matches = 0;
+  int total_num_assets_with_size = 0;
+  for (const auto& [asset, topic] : pending_dynamic_asset_topics_) {
+    if (!asset->size()) {
+      DVLOG(4) << "Ignoring dynamic image asset with no size specified in "
+                  "animation file";
+      continue;
+    }
+
+    ++total_num_assets_with_size;
+    if (IsPortrait(asset->size().value()) == IsPortrait(topic.photo.size()))
+      ++num_photo_orientation_matches;
+  }
+
+  if (total_num_assets_with_size == 0) {
+    LOG(WARNING) << "Found no image assets in animation with a specified size";
+    return;
+  }
+
+  float match_percentage =
+      num_photo_orientation_matches * 100.f / total_num_assets_with_size;
+  ambient::RecordAmbientModePhotoOrientationMatch(
+      match_percentage, static_resources_->GetAmbientAnimationTheme());
+}
+
 }  // namespace ash
diff --git a/ash/ambient/model/ambient_animation_photo_provider.h b/ash/ambient/model/ambient_animation_photo_provider.h
index ac8835c..13b383e 100644
--- a/ash/ambient/model/ambient_animation_photo_provider.h
+++ b/ash/ambient/model/ambient_animation_photo_provider.h
@@ -99,6 +99,7 @@
   GetTopicsToChooseFrom() const;
 
   void NotifyObserverOfNewTopics();
+  void RecordDynamicAssetMetrics();
 
   // Unowned pointers. Must outlive the |AmbientAnimationPhotoProvider|.
   const AmbientAnimationStaticResources* const static_resources_;
diff --git a/ash/ambient/model/ambient_animation_photo_provider_unittest.cc b/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
index 3f1e02d..8f59eae5 100644
--- a/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
+++ b/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/scoped_observation.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "cc/paint/skottie_frame_data.h"
 #include "cc/paint/skottie_resource_metadata.h"
@@ -704,4 +705,52 @@
   Mock::VerifyAndClearExpectations(&observer);
 }
 
+TEST_F(AmbientAnimationPhotoProviderTest, RecordsPhotoOrientationMatch) {
+  static_resources_.set_ambient_animation_theme(
+      AmbientAnimationTheme::kFeelTheBreeze);
+
+  // 2 landscape 2 portrait
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/10, /*height=*/20));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/20, /*height=*/10));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/20, /*height=*/40));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/40, /*height=*/20));
+
+  std::vector<scoped_refptr<ImageAsset>> all_assets =
+      LoadAllDynamicAssets({gfx::Size(100, 50), gfx::Size(50, 100),
+                            gfx::Size(100, 50), gfx::Size(50, 100)});
+  {
+    base::HistogramTester histogram_tester;
+    GetFrameDataForAssets(all_assets, /*timestamp=*/0);
+    GetFrameDataForAssets(all_assets, /*timestamp=*/1);
+    histogram_tester.ExpectUniqueSample(
+        "Ash.AmbientMode.PhotoOrientationMatch.FeelTheBreeze", 100, 1);
+  }
+
+  // 3 landscape 1 portrait
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/10, /*height=*/20));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/60, /*height=*/30));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/80, /*height=*/40));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/100, /*height=*/50));
+  {
+    base::HistogramTester histogram_tester;
+    GetFrameDataForAssets(all_assets, /*timestamp=*/0);
+    GetFrameDataForAssets(all_assets, /*timestamp=*/1);
+    histogram_tester.ExpectUniqueSample(
+        "Ash.AmbientMode.PhotoOrientationMatch.FeelTheBreeze", 75, 1);
+  }
+
+  // // 1 landscape 3 portrait
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/30, /*height=*/60));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/20, /*height=*/10));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/40, /*height=*/80));
+  AddImageToModel(gfx::test::CreateImageSkia(/*width=*/50, /*height=*/100));
+  {
+    base::HistogramTester histogram_tester;
+    GetFrameDataForAssets(all_assets, /*timestamp=*/0);
+    GetFrameDataForAssets(all_assets, /*timestamp=*/1);
+    histogram_tester.ExpectUniqueSample(
+        "Ash.AmbientMode.PhotoOrientationMatch.FeelTheBreeze", 75, 1);
+  }
+}
+
 }  // namespace ash
diff --git a/ash/ambient/test/fake_ambient_animation_static_resources.cc b/ash/ambient/test/fake_ambient_animation_static_resources.cc
index dd6a958..9af6a4d7 100644
--- a/ash/ambient/test/fake_ambient_animation_static_resources.cc
+++ b/ash/ambient/test/fake_ambient_animation_static_resources.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "ash/constants/ambient_animation_theme.h"
 #include "base/check.h"
 #include "base/notreached.h"
 #include "cc/paint/skottie_wrapper.h"
@@ -47,7 +46,7 @@
 
 AmbientAnimationTheme
 FakeAmbientAnimationStaticResources::GetAmbientAnimationTheme() const {
-  return AmbientAnimationTheme::kFeelTheBreeze;
+  return ambient_animation_theme_;
 }
 
 }  // namespace ash
diff --git a/ash/ambient/test/fake_ambient_animation_static_resources.h b/ash/ambient/test/fake_ambient_animation_static_resources.h
index 8cb2dc4..7a16bf0 100644
--- a/ash/ambient/test/fake_ambient_animation_static_resources.h
+++ b/ash/ambient/test/fake_ambient_animation_static_resources.h
@@ -10,6 +10,7 @@
 
 #include "ash/ambient/resources/ambient_animation_static_resources.h"
 #include "ash/ash_export.h"
+#include "ash/constants/ambient_animation_theme.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_piece.h"
@@ -43,6 +44,11 @@
   // GetStaticImageAsset() will return a null image.
   void SetStaticImageAsset(base::StringPiece asset_id, gfx::ImageSkia image);
 
+  void set_ambient_animation_theme(
+      AmbientAnimationTheme ambient_animation_theme) {
+    ambient_animation_theme_ = ambient_animation_theme;
+  }
+
   // AmbientAnimationStaticResources implementation:
   const scoped_refptr<cc::SkottieWrapper>& GetSkottieWrapper() const override;
   gfx::ImageSkia GetStaticImageAsset(base::StringPiece asset_id) const override;
@@ -51,6 +57,8 @@
  private:
   scoped_refptr<cc::SkottieWrapper> animation_;
   base::flat_map</*asset_id*/ std::string, gfx::ImageSkia> images_;
+  AmbientAnimationTheme ambient_animation_theme_ =
+      AmbientAnimationTheme::kFeelTheBreeze;
 };
 
 }  // namespace ash
diff --git a/ash/components/hid_detection/hid_detection_utils.cc b/ash/components/hid_detection/hid_detection_utils.cc
index 92596c06..70d97d60 100644
--- a/ash/components/hid_detection/hid_detection_utils.cc
+++ b/ash/components/hid_detection/hid_detection_utils.cc
@@ -72,19 +72,4 @@
                                 hid_type.value());
 }
 
-void RecordHidDisconnected(const device::mojom::InputDeviceInfo& device) {
-  absl::optional<HidType> hid_type = GetHidType(device);
-
-  // If |device| is not relevant (i.e. an accelerometer, joystick, etc), don't
-  // emit metric.
-  if (!hid_type.has_value()) {
-    HID_LOG(DEBUG) << "HidDisconnected not logged for device " << device.id
-                   << " because it doesn't have a relevant device type.";
-    return;
-  }
-
-  base::UmaHistogramEnumeration("OOBE.HidDetectionScreen.HidDisconnected",
-                                hid_type.value());
-}
-
 }  // namespace ash::hid_detection
diff --git a/ash/components/hid_detection/hid_detection_utils.h b/ash/components/hid_detection/hid_detection_utils.h
index c1b6075..705da41 100644
--- a/ash/components/hid_detection/hid_detection_utils.h
+++ b/ash/components/hid_detection/hid_detection_utils.h
@@ -36,9 +36,6 @@
 // Record each HID that is connected while the HID detection screen is shown.
 void RecordHidConnected(const device::mojom::InputDeviceInfo& device);
 
-// Record each HID that is disconnected while the HID detection screen is shown.
-void RecordHidDisconnected(const device::mojom::InputDeviceInfo& device);
-
 }  // namespace ash::hid_detection
 
 #endif  // ASH_COMPONENTS_HID_DETECTION_HID_DETECTION_UTILS_H_
diff --git a/ash/components/phonehub/camera_roll_download_manager.h b/ash/components/phonehub/camera_roll_download_manager.h
index 346ef1c..075eb1ed 100644
--- a/ash/components/phonehub/camera_roll_download_manager.h
+++ b/ash/components/phonehub/camera_roll_download_manager.h
@@ -33,7 +33,10 @@
     kPayloadAlreadyExists,
     // The payload files cannot be created because there is not enough free disk
     // space for the item requested.
-    kInsufficientDiskSpace
+    kInsufficientDiskSpace,
+    // The payload files cannot be created because a file already exists at the
+    // target path, likely a result of some race conditions.
+    kNotUniqueFilePath,
   };
 
   // Creates payload files that can be used to receive an incoming file transfer
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index f6318ad9..7b0e3c5 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -598,8 +598,8 @@
     "EnableOobeNetworkScreenSkip", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables skipping of network screen.
-const base::Feature kEnableOobeThemeSelection{"EnableOobeThemeSelection",
-                                              base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kEnableOobeThemeSelection{
+    "EnableOobeThemeSelection", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enables showing notification after the password change for SAML users.
 const base::Feature kEnableSamlNotificationOnPasswordChangeSuccess{
diff --git a/ash/public/cpp/ambient/DIR_METADATA b/ash/public/cpp/ambient/DIR_METADATA
index 5cf9e51..e8a674f9 100644
--- a/ash/public/cpp/ambient/DIR_METADATA
+++ b/ash/public/cpp/ambient/DIR_METADATA
@@ -1,3 +1 @@
-monorail {
-  component: "UI>Shell>Assistant"
-}
+mixins: "//ash/ambient/COMMON_METADATA"
diff --git a/ash/public/cpp/ambient/ambient_metrics.cc b/ash/public/cpp/ambient/ambient_metrics.cc
index b94a530..a1fcd1f 100644
--- a/ash/public/cpp/ambient/ambient_metrics.cc
+++ b/ash/public/cpp/ambient/ambient_metrics.cc
@@ -107,5 +107,12 @@
       smoothness);
 }
 
+void RecordAmbientModePhotoOrientationMatch(int percentage_match,
+                                            AmbientAnimationTheme theme) {
+  base::UmaHistogramPercentage(
+      base::StrCat({"Ash.AmbientMode.PhotoOrientationMatch.", ToString(theme)}),
+      percentage_match);
+}
+
 }  // namespace ambient
 }  // namespace ash
diff --git a/ash/public/cpp/ambient/ambient_metrics.h b/ash/public/cpp/ambient/ambient_metrics.h
index 38645b4..c86a9ac3 100644
--- a/ash/public/cpp/ambient/ambient_metrics.h
+++ b/ash/public/cpp/ambient/ambient_metrics.h
@@ -47,6 +47,10 @@
     int smoothness,
     AmbientAnimationTheme theme);
 
+ASH_PUBLIC_EXPORT void RecordAmbientModePhotoOrientationMatch(
+    int percentage_match,
+    AmbientAnimationTheme theme);
+
 }  // namespace ambient
 }  // namespace ash
 
diff --git a/ash/services/secure_channel/ble_characteristics_finder.cc b/ash/services/secure_channel/ble_characteristics_finder.cc
index 4881883..0eb9dbb 100644
--- a/ash/services/secure_channel/ble_characteristics_finder.cc
+++ b/ash/services/secure_channel/ble_characteristics_finder.cc
@@ -222,11 +222,7 @@
 
 bool BluetoothLowEnergyCharacteristicsFinder::DoesEidMatchExpectedDevice(
     const std::vector<uint8_t>& eid_value_read) {
-  // Convert the char data from a std::vector<uint8_t> to a std::string.
-  std::string eid_char_data_str;
-  char* string_contents_ptr =
-      base::WriteInto(&eid_char_data_str, eid_value_read.size() + 1);
-  memcpy(string_contents_ptr, eid_value_read.data(), eid_value_read.size());
+  std::string eid_char_data_str(eid_value_read.begin(), eid_value_read.end());
 
   multidevice::RemoteDeviceRefList remote_device_list{remote_device_};
   std::string identified_device_id =
diff --git a/ash/services/secure_channel/ble_scanner_impl.cc b/ash/services/secure_channel/ble_scanner_impl.cc
index d07e6e8..880350ad 100644
--- a/ash/services/secure_channel/ble_scanner_impl.cc
+++ b/ash/services/secure_channel/ble_scanner_impl.cc
@@ -204,12 +204,7 @@
     return;
   }
 
-  // Convert the service data from a std::vector<uint8_t> to a std::string.
-  std::string service_data_str;
-  char* string_contents_ptr =
-      base::WriteInto(&service_data_str, service_data->size() + 1);
-  memcpy(string_contents_ptr, service_data->data(), service_data->size());
-
+  std::string service_data_str(service_data->begin(), service_data->end());
   auto potential_result = bluetooth_helper_->IdentifyRemoteDevice(
       service_data_str, GetAllDeviceIdPairs());
 
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
index eb73fadc5..a5ec3dd 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
+++ b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
@@ -51,9 +51,9 @@
   <iron-selector id="selector" selected="0"
       selected-item="{{selectedButton_}}">
     <cr-button id="lightMode" data-color-mode="LIGHT"
-        on-click="onClickColorModeButton_" role="button"
+        on-click="onClickColorModeButton_"
         aria-pressed$="[[getLightAriaPressed_(colorModeAutoScheduleEnabled_, darkModeEnabled_)]]"
-        aria-label="$i18n{ariaLabelEnableLightColorMode}">
+        aria-description="$i18n{ariaLabelEnableLightColorMode}">
       <iron-icon icon="personalization:light" aria-hidden="true"></iron-icon>
       <div class="text">$i18n{lightColorMode}</div>
     </cr-button>
@@ -61,7 +61,7 @@
         on-click="onClickColorModeButton_"
         on-keypress="onClickColorModeButton_" tabindex="-1"
         aria-pressed$="[[getDarkAriaPressed_(colorModeAutoScheduleEnabled_, darkModeEnabled_)]]"
-        aria-label="$i18n{ariaLabelEnableDarkColorMode}">
+        aria-description="$i18n{ariaLabelEnableDarkColorMode}">
       <iron-icon icon="personalization:dark" aria-hidden="true"></iron-icon>
       <div class="text">$i18n{darkColorMode}</div>
     </cr-button>
@@ -69,7 +69,7 @@
         on-click="onClickAutoModeButton_"
         on-keypress="onClickAutoModeButton_" tabindex="-1"
         aria-pressed$="[[getAutoAriaPressed_(colorModeAutoScheduleEnabled_)]]"
-        aria-label="$i18n{ariaLabelEnableAutoColorMode}">
+        aria-description="$i18n{ariaLabelEnableAutoColorMode}">
       <iron-icon icon="personalization:auto" aria-hidden="true"></iron-icon>
       <div class="text">$i18n{autoColorMode}</div>
     </cr-button>
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts
index 01793a9..30da1c9 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts
@@ -45,8 +45,14 @@
   static get properties() {
     return {
       // null indicates value is being loaded.
-      darkModeEnabled_: Boolean,
-      colorModeAutoScheduleEnabled_: Boolean,
+      darkModeEnabled_: {
+        type: Boolean,
+        value: null,
+      },
+      colorModeAutoScheduleEnabled_: {
+        type: Boolean,
+        value: null,
+      },
 
       /** The button currently highlighted by keyboard navigation. */
       selectedButton_: {
@@ -56,8 +62,8 @@
     };
   }
 
-  private darkModeEnabled_: boolean|null = null;
-  private colorModeAutoScheduleEnabled_: boolean|null = null;
+  private darkModeEnabled_: boolean|null;
+  private colorModeAutoScheduleEnabled_: boolean|null;
   private selectedButton_: CrButtonElement;
 
   override ready() {
@@ -117,7 +123,7 @@
         .toString();
   }
 
-  private getDarkAriaPressed_() {
+  private getDarkAriaPressed_(): string {
     //  If auto schedule mode is enabled, the system disregards whether dark
     //  mode is enabled or not. To ensure expected behavior, we show that light
     //  mode is selected only when both auto schedule mode and dark mode are
@@ -126,7 +132,7 @@
         .toString();
   }
 
-  private getAutoAriaPressed_() {
+  private getAutoAriaPressed_(): string {
     return (!!this.colorModeAutoScheduleEnabled_).toString();
   }
 
diff --git a/ash/webui/personalization_app/resources/untrusted/collections_grid.html b/ash/webui/personalization_app/resources/untrusted/collections_grid.html
index 4030ce5..cb061d5e2 100644
--- a/ash/webui/personalization_app/resources/untrusted/collections_grid.html
+++ b/ash/webui/personalization_app/resources/untrusted/collections_grid.html
@@ -138,18 +138,27 @@
     display: none;
   }
 </style>
-<iron-list items="[[tiles_]]" grid>
+<iron-list items="[[tiles_]]"
+    grid
+    role="listbox"
+    aria-setsize$="[[tiles_.length]]">
   <template>
     <div class="photo-container">
       <template is="dom-if" if="[[isLoadingTile_(item)]]">
-        <div tabindex$="[[tabIndex]]" role="button"
+        <div tabindex$="[[tabIndex]]"
+            role="option"
             class="photo-inner-container placeholder"
             style$="[[getLoadingPlaceholderAnimationDelay(index)]]"
-            aria-label$="[[geti18n_('ariaLabelLoading')]]" aria-disabled="true">
+            aria-posinset$="[[getAriaIndex_(index)]]"
+            aria-label$="[[geti18n_('ariaLabelLoading')]]"
+            aria-disabled="true">
         </div>
       </template>
       <template is="dom-if" if="[[isFailureTile_(item)]]">
-        <div tabindex$="[[tabIndex]]" role="button" aria-disabled="true"
+        <div tabindex$="[[tabIndex]]"
+            role="button"
+            aria-posinset$="[[getAriaIndex_(index)]]"
+            aria-disabled="true"
             class="photo-inner-container photo-loading-failure">
           <div class$="[[getClassForImagesContainer_(item)]]">
             <template is="dom-repeat" items="[[item.preview]]" as="preview">
@@ -166,7 +175,9 @@
       </div>
       </template>
       <template is="dom-if" if="[[isEmptyTile_(item)]]">
-        <div tabindex$="[[tabIndex]]" role="button"
+        <div tabindex$="[[tabIndex]]"
+            role="option"
+            aria-posinset$="[[getAriaIndex_(index)]]"
             aria-disabled$="[[getTileAriaDisabled_(item)]]"
             class$="[[getClassForEmptyTile_(item)]]"
             managed$="[[isManagedTile_(item)]]"
@@ -190,7 +201,9 @@
         </div>
       </template>
       <template is="dom-if" if="[[isImageTile_(item)]]">
-        <div class="photo-inner-container" role="button"
+        <div class="photo-inner-container"
+            role="option"
+            aria-posinset$="[[getAriaIndex_(index)]]"
             on-click="onCollectionSelected_"
             on-keypress="onCollectionSelected_"
             tabindex$="[[tabIndex]]">
diff --git a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
index e4a5b6f4..3ce7f8a 100644
--- a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
+++ b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
@@ -468,6 +468,10 @@
       elem.removeAttribute('hidden');
     }
   }
+
+  private getAriaIndex_(index: number): number {
+    return index + 1;
+  }
 }
 
 customElements.define(CollectionsGrid.is, CollectionsGrid);
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.html b/ash/webui/personalization_app/resources/untrusted/images_grid.html
index 2a50117..51308fe7 100644
--- a/ash/webui/personalization_app/resources/untrusted/images_grid.html
+++ b/ash/webui/personalization_app/resources/untrusted/images_grid.html
@@ -9,10 +9,13 @@
     <template>
       <div class="photo-container">
         <template is="dom-if" if="[[isLoadingTile_(item)]]">
-          <div tabindex$="[[tabIndex]]" role="button"
+          <div tabindex$="[[tabIndex]]"
+              role="option"
               class="photo-inner-container placeholder"
               style$="[[getLoadingPlaceholderAnimationDelay_(index)]]"
-              aria-label="$i18n{ariaLabelLoading}" aria-disabled="true"></div>
+              aria-posinset$="[[getAriaIndex_(index)]]"
+              aria-label="$i18n{ariaLabelLoading}"
+              aria-disabled="true"></div>
         </template>
         <template is="dom-if" if="[[isImageTile_(item)]]">
           <div class="photo-inner-container" tabindex$="[[tabIndex]]"
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index 0680de1..d9cb4b78 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -362,6 +362,8 @@
     return;
   }
   std::move(callback).Run(version_updater_.UpdateOs());
+
+  SendMetricOnUpdateOs();
 }
 
 void ShimlessRmaService::UpdateOsSkipped(UpdateOsSkippedCallback callback) {
@@ -1071,6 +1073,16 @@
                               weak_ptr_factory_.GetWeakPtr()));
 }
 
+void ShimlessRmaService::SendMetricOnUpdateOs() {
+  rmad::RecordBrowserActionMetricRequest request;
+  request.set_diagnostics(false);
+  request.set_os_update(true);
+
+  RmadClient::Get()->RecordBrowserActionMetric(
+      request, base::BindOnce(&ShimlessRmaService::OnMetricsReply,
+                              weak_ptr_factory_.GetWeakPtr()));
+}
+
 void ShimlessRmaService::OnMetricsReply(
     absl::optional<rmad::RecordBrowserActionMetricReply> response) {
   if (!response) {
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.h b/ash/webui/shimless_rma/backend/shimless_rma_service.h
index fa8d20f7..798b84e3 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.h
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.h
@@ -190,6 +190,9 @@
   // Sends a metric to the platform side when the Diagnostics app is launched.
   void SendMetricOnLaunchDiagnostics();
 
+  // Sends a metric to the platform side when an OS update is requested.
+  void SendMetricOnUpdateOs();
+
  private:
   using TransitionStateCallback =
       base::OnceCallback<void(mojom::State, bool, bool, rmad::RmadErrorCode)>;
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
index e3af915..2e708f8 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -3280,6 +3280,56 @@
   EXPECT_FALSE(fake_rmad_client_()->GetMetricOsUpdate());
 }
 
+TEST_F(ShimlessRmaServiceTest, OsUpdateSendsMetric) {
+  // Connect to wifi so that we can skip the network page.
+  SetupWiFiNetwork(kDefaultWifiGuid);
+
+  // Since OS Update is only a mojo state, and not an rmad state, we have
+  // to start at the landing page, and skip two pages to get to OS Update.
+  const std::vector<rmad::GetStateReply> fake_states = {
+      CreateStateReply(rmad::RmadState::kWelcome, rmad::RMAD_ERROR_OK)};
+  fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states));
+
+  base::RunLoop run_loop_1;
+
+  // Initialize current state
+  shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting(
+      [&](mojom::State state, bool can_cancel, bool can_go_back,
+          rmad::RmadErrorCode error) {
+        EXPECT_EQ(state, mojom::State::kWelcomeScreen);
+        EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK);
+      }));
+  run_loop_1.RunUntilIdle();
+
+  // Move to the next page. This should be the OS Update page.
+  shimless_rma_provider_->BeginFinalization(base::BindLambdaForTesting(
+      [&](mojom::State state, bool can_exit, bool can_go_back,
+          rmad::RmadErrorCode error) {
+        EXPECT_EQ(state, mojom::State::kUpdateOs);
+        EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK);
+        run_loop_1.Quit();
+      }));
+  run_loop_1.Run();
+
+  // Now, actually test the OS Update page.
+  base::RunLoop run_loop_2;
+
+  fake_rmad_client_()->SetRecordBrowserActionMetricReply(rmad::RMAD_ERROR_OK);
+
+  EXPECT_EQ(0u, fake_rmad_client_()->GetRecordBrowserActionMetricCount());
+
+  shimless_rma_provider_->UpdateOs(
+      base::BindLambdaForTesting([&](bool update_started) {
+        EXPECT_TRUE(update_started);
+        run_loop_2.Quit();
+      }));
+  run_loop_2.Run();
+
+  EXPECT_EQ(1u, fake_rmad_client_()->GetRecordBrowserActionMetricCount());
+  EXPECT_TRUE(fake_rmad_client_()->GetMetricOsUpdate());
+  EXPECT_FALSE(fake_rmad_client_()->GetMetricDiagnostics());
+}
+
 class FakeErrorObserver : public mojom::ErrorObserver {
  public:
   void OnError(rmad::RmadErrorCode error) override {
diff --git a/ash/webui/shimless_rma/backend/version_updater.cc b/ash/webui/shimless_rma/backend/version_updater.cc
index 41a4858..4ac1d5e 100644
--- a/ash/webui/shimless_rma/backend/version_updater.cc
+++ b/ash/webui/shimless_rma/backend/version_updater.cc
@@ -131,10 +131,12 @@
     return false;
   }
 
-  if (!IsUpdateEngineIdle()) {
-    LOG(ERROR) << "Tried to start update when UpdateEngine not IDLE.";
-    return false;
-  }
+  // TODO(swifton): Find out if we need to add an observer to the update engine
+  // client.
+
+  // TODO(swifton): Find out how the state of the engine client should be
+  // checked after using RequestUpdateCheckWithoutApplying.
+
   // RequestUpdateCheck will check if an update is available and install it.
   DBusThreadManager::Get()->GetUpdateEngineClient()->RequestUpdateCheck(
       base::BindOnce(&VersionUpdater::OnRequestUpdateCheck,
diff --git a/ash/wm/desks/autotest_desks_api_unittests.cc b/ash/wm/desks/autotest_desks_api_unittests.cc
index 170f731..bf802a9c 100644
--- a/ash/wm/desks/autotest_desks_api_unittests.cc
+++ b/ash/wm/desks/autotest_desks_api_unittests.cc
@@ -9,7 +9,6 @@
 #include "ash/wm/desks/desks_util.h"
 #include "base/callback_helpers.h"
 #include "base/run_loop.h"
-#include "components/viz/common/features.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 
 namespace ash {
@@ -112,9 +111,7 @@
 
 // TODO(b/219068687): Re-enable chained desk animation tests.
 TEST_F(EnhancedDeskAnimationsAutotestDesksApiTest,
-       ActivateAdjacentDesksToTargetIndex) {
-  if (::features::IsUsingSkiaRenderer())
-    GTEST_SKIP() << "Chained desk animations are flaky on SkiaRenderer.";
+       DISABLED_ActivateAdjacentDesksToTargetIndex) {
   // Create all desks possible.
   AutotestDesksApi test_api;
   const int max_number_of_desks = desks_util::kMaxNumberOfDesks;
diff --git a/ash/wm/desks/root_window_desk_switch_animator_unittest.cc b/ash/wm/desks/root_window_desk_switch_animator_unittest.cc
index d38283c..69817cc5 100644
--- a/ash/wm/desks/root_window_desk_switch_animator_unittest.cc
+++ b/ash/wm/desks/root_window_desk_switch_animator_unittest.cc
@@ -13,7 +13,6 @@
 #include "ash/wm/desks/desks_histogram_enums.h"
 #include "ash/wm/desks/root_window_desk_switch_animator_test_api.h"
 #include "base/run_loop.h"
-#include "components/viz/common/features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 
@@ -181,9 +180,8 @@
 // TODO(b/219068687): Re-enable chained desk animation tests.
 // Tests a chained animation where the replaced animation already has a
 // screenshot layer stored.
-TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationNoNewScreenshot) {
-  if (::features::IsUsingSkiaRenderer())
-    GTEST_SKIP() << "Chained desk animations are flaky on SkiaRenderer.";
+TEST_F(RootWindowDeskSwitchAnimatorTest,
+       DISABLED_ChainedAnimationNoNewScreenshot) {
   InitAnimator(1, 2);
   TakeStartingDeskScreenshotAndWait();
   TakeEndingDeskScreenshotAndWait();
@@ -214,11 +212,10 @@
                              animation_layer));
 }
 
+// TODO(b/219068687): Re-enable chained desk animation tests.
 // Tests a chained animation where we are adding an animation to the right of
 // the current animating desks, causing the animation layer to shift left.
-TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationMovingLeft) {
-  if (::features::IsUsingSkiaRenderer())
-    GTEST_SKIP() << "Chained desk animations are flaky on SkiaRenderer.";
+TEST_F(RootWindowDeskSwitchAnimatorTest, DISABLED_ChainedAnimationMovingLeft) {
   InitAnimator(1, 2);
   TakeStartingDeskScreenshotAndWait();
   TakeEndingDeskScreenshotAndWait();
@@ -258,11 +255,10 @@
                              animation_layer));
 }
 
+// TODO(b/219068687): Re-enable chained desk animation tests.
 // Tests a chained animation where we are adding an animation to the left of
 // the current animating desks, causing the animation layer to shift right.
-TEST_F(RootWindowDeskSwitchAnimatorTest, ChainedAnimationMovingRight) {
-  if (::features::IsUsingSkiaRenderer())
-    GTEST_SKIP() << "Chained desk animations are flaky on SkiaRenderer.";
+TEST_F(RootWindowDeskSwitchAnimatorTest, DISABLED_ChainedAnimationMovingRight) {
   InitAnimator(3, 2);
   TakeStartingDeskScreenshotAndWait();
   TakeEndingDeskScreenshotAndWait();
@@ -299,10 +295,9 @@
                              animation_layer));
 }
 
+// TODO(b/219068687): Re-enable chained desk animation tests.
 // Tests a complex animation which multiple animations are started and replaced.
-TEST_F(RootWindowDeskSwitchAnimatorTest, MultipleReplacements) {
-  if (::features::IsUsingSkiaRenderer())
-    GTEST_SKIP() << "Chained desk animations are flaky on SkiaRenderer.";
+TEST_F(RootWindowDeskSwitchAnimatorTest, DISABLED_MultipleReplacements) {
   InitAnimator(1, 2);
   TakeStartingDeskScreenshotAndWait();
   TakeEndingDeskScreenshotAndWait();
diff --git a/ash/wm/desks/templates/saved_desk_item_view.cc b/ash/wm/desks/templates/saved_desk_item_view.cc
index 4e0b44f..012b3db9 100644
--- a/ash/wm/desks/templates/saved_desk_item_view.cc
+++ b/ash/wm/desks/templates/saved_desk_item_view.cc
@@ -289,12 +289,13 @@
 void SavedDeskItemView::MaybeRemoveNameNumber() {
   // When there are existing matched Desk name and Template name (ie.
   // "Desk 1"), creating a new template from "Desk 1" will get auto generated
-  // template name from backend as "Desk 1 (1)", to prevent template
+  // template name from the frontend as "Desk 1 (1)", to prevent template
   // duplication, we show the template view name to be "Desk 1" by removing name
   // number, save template under such name will call out template replace
   // dialog.
-  if (FindOtherTemplateWithName(
-          DesksController::Get()->active_desk()->name())) {
+  if (saved_desk_util::GetSavedDeskPresenter()->FindOtherEntryWithName(
+          DesksController::Get()->active_desk()->name(), desk_template().type(),
+          uuid())) {
     // Replace the name number.
     name_view_->SetTemporaryName(DesksController::Get()->active_desk()->name());
     name_view_->SetViewName(DesksController::Get()->active_desk()->name());
@@ -487,29 +488,30 @@
   // still being activated. In this case, we don't want to show the dialog and
   // activate its associated widget until after the desks bar widget is finished
   // activating. See https://crbug.com/1301759.
-  auto* template_to_replace = FindOtherTemplateWithName(name_view_->GetText());
+  auto* template_to_replace =
+      saved_desk_util::GetSavedDeskPresenter()->FindOtherEntryWithName(
+          name_view_->GetText(), desk_template().type(), uuid());
   if (template_to_replace) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&SavedDeskItemView::MaybeShowReplaceDialog,
-                       weak_ptr_factory_.GetWeakPtr(), template_to_replace));
+        FROM_HERE, base::BindOnce(&SavedDeskItemView::MaybeShowReplaceDialog,
+                                  weak_ptr_factory_.GetWeakPtr(),
+                                  template_to_replace->type(),
+                                  template_to_replace->uuid()));
     return;
   }
 
   UpdateTemplateName();
 }
 
-void SavedDeskItemView::MaybeShowReplaceDialog(
-    SavedDeskItemView* template_to_replace) {
+void SavedDeskItemView::MaybeShowReplaceDialog(DeskTemplateType type,
+                                               const base::GUID& uuid) {
   // Show replace template dialog. If accepted, replace old template and commit
   // name change.
   aura::Window* root_window = GetWidget()->GetNativeWindow()->GetRootWindow();
   saved_desk_util::GetSavedDeskDialogController()->ShowReplaceDialog(
-      root_window, name_view_->GetText(),
-      template_to_replace->desk_template_->type(),
-      base::BindOnce(
-          &SavedDeskItemView::ReplaceTemplate, weak_ptr_factory_.GetWeakPtr(),
-          template_to_replace->desk_template_->uuid().AsLowercaseString()),
+      root_window, name_view_->GetText(), type,
+      base::BindOnce(&SavedDeskItemView::ReplaceTemplate,
+                     weak_ptr_factory_.GetWeakPtr(), uuid.AsLowercaseString()),
       base::BindOnce(&SavedDeskItemView::RevertTemplateName,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -637,22 +639,6 @@
   return views::ViewTargeterDelegate::TargetForRect(root, rect);
 }
 
-SavedDeskItemView* SavedDeskItemView::FindOtherTemplateWithName(
-    const std::u16string& name) const {
-  const auto templates_grid_view_items =
-      static_cast<const SavedDeskGridView*>(parent())->grid_items();
-
-  auto iter = std::find_if(
-      templates_grid_view_items.begin(), templates_grid_view_items.end(),
-      [this, name](const SavedDeskItemView* d) {
-        // Name duplication is allowed if one of the templates is an admin
-        // template.
-        return (d != this && d->desk_template_->template_name() == name &&
-                d->desk_template_->source() != DeskTemplateSource::kPolicy);
-      });
-  return iter == templates_grid_view_items.end() ? nullptr : *iter;
-}
-
 void SavedDeskItemView::OnDeleteTemplate() {
   saved_desk_util::GetSavedDeskPresenter()->DeleteEntry(
       desk_template_->uuid().AsLowercaseString(), desk_template_->type());
diff --git a/ash/wm/desks/templates/saved_desk_item_view.h b/ash/wm/desks/templates/saved_desk_item_view.h
index 60f59884..172d8d3 100644
--- a/ash/wm/desks/templates/saved_desk_item_view.h
+++ b/ash/wm/desks/templates/saved_desk_item_view.h
@@ -95,7 +95,8 @@
   // so, remove auto added number.
   void MaybeRemoveNameNumber();
   // Show replace dialog when found a name duplication.
-  void MaybeShowReplaceDialog(SavedDeskItemView* saved_desk_to_replace);
+  void MaybeShowReplaceDialog(ash::DeskTemplateType type,
+                              const base::GUID& uuid);
   // Rename current saved desk with new name, delete old saved desk with same
   // name by uuid. Used for callback functions for Replace Dialog.
   void ReplaceTemplate(const std::string& uuid);
@@ -130,11 +131,6 @@
  private:
   friend class SavedDeskItemViewTestApi;
 
-  // Return the duplicated saved desk item if there is a name duplication in
-  // saved desks.
-  SavedDeskItemView* FindOtherTemplateWithName(
-      const std::u16string& name) const;
-
   void OnDeleteTemplate();
   void OnDeleteButtonPressed();
 
diff --git a/ash/wm/desks/templates/saved_desk_presenter.cc b/ash/wm/desks/templates/saved_desk_presenter.cc
index 4466286..df1b5ea5 100644
--- a/ash/wm/desks/templates/saved_desk_presenter.cc
+++ b/ash/wm/desks/templates/saved_desk_presenter.cc
@@ -28,6 +28,8 @@
 #include "base/bind.h"
 #include "base/i18n/number_formatting.h"
 #include "base/time/time.h"
+#include "components/desks_storage/core/desk_template_util.h"
+#include "third_party/re2/src/re2/re2.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace ash {
@@ -39,6 +41,13 @@
     "MaximumDeskLaunchTemplateToast";
 constexpr char kTemplateTooLargeToastName[] = "TemplateTooLargeToast";
 
+// Duplicate value format.
+constexpr char kDuplicateNumberFormat[] = "(%d)";
+// Initial duplicate number value.
+constexpr char kInitialDuplicateNumberValue[] = " (1)";
+// Regex used in determining if duplicate name should be incremented.
+constexpr char kDuplicateNumberRegex[] = "\\(([0-9]+)\\)$";
+
 // Helper to get the desk model from the shell delegate. Should always return a
 // usable desk model, either from chrome sync, or a local storage.
 desks_storage::DeskModel* GetDeskModel() {
@@ -78,6 +87,13 @@
              : model->GetMaxSaveAndRecallDeskEntryCount();
 }
 
+ash::DeskTemplate* SavedDeskPresenter::FindOtherEntryWithName(
+    const std::u16string& name,
+    ash::DeskTemplateType type,
+    const base::GUID& uuid) const {
+  return GetDeskModel()->FindOtherEntryWithName(name, type, uuid);
+}
+
 void SavedDeskPresenter::UpdateDesksTemplatesUI() {
   // This function:
   //  1. Figures out whether the library button should be shown in the desk bar.
@@ -184,6 +200,16 @@
   else
     RecordWindowAndTabCountHistogram(*desk_template);
 
+  // While we still find duplicate names iterate the duplicate number. i.e.
+  // if there are 4 duplicates of some template name then this iterates until
+  // the current template will be named 5.
+  while (GetDeskModel()->FindOtherEntryWithName(desk_template->template_name(),
+                                                desk_template->type(),
+                                                desk_template->uuid())) {
+    desk_template->set_template_name(
+        AppendDuplicateNumberToDuplicateName(desk_template->template_name()));
+  }
+
   // Clone the desk template so one can be sent to the model, and the other as
   // part of the callback.
   // TODO: Investigate if we can modify the model to send the template as one of
@@ -451,4 +477,21 @@
     std::move(on_update_ui_closure_for_testing_).Run();
 }
 
+std::u16string SavedDeskPresenter::AppendDuplicateNumberToDuplicateName(
+    const std::u16string& duplicate_name_u16) {
+  std::string duplicate_name = base::UTF16ToUTF8(duplicate_name_u16);
+  int found_duplicate_number;
+
+  if (RE2::PartialMatch(duplicate_name, kDuplicateNumberRegex,
+                        &found_duplicate_number)) {
+    RE2::Replace(
+        &duplicate_name, kDuplicateNumberRegex,
+        base::StringPrintf(kDuplicateNumberFormat, found_duplicate_number + 1));
+  } else {
+    duplicate_name.append(kInitialDuplicateNumberValue);
+  }
+
+  return base::UTF8ToUTF16(duplicate_name);
+}
+
 }  // namespace ash
diff --git a/ash/wm/desks/templates/saved_desk_presenter.h b/ash/wm/desks/templates/saved_desk_presenter.h
index 4a41a20..e46f693 100644
--- a/ash/wm/desks/templates/saved_desk_presenter.h
+++ b/ash/wm/desks/templates/saved_desk_presenter.h
@@ -42,6 +42,12 @@
   size_t GetEntryCount(DeskTemplateType type) const;
   size_t GetMaxEntryCount(DeskTemplateType type) const;
 
+  // Finds an entry of type `type` with the name `name` that is not the entry
+  // identified by `uuid`. Returns nullptr if not found.
+  ash::DeskTemplate* FindOtherEntryWithName(const std::u16string& name,
+                                            ash::DeskTemplateType type,
+                                            const base::GUID& uuid) const;
+
   // Update the buttons of the desks templates UI and the visibility of the
   // templates grid. The grid contents are not updated. Updates
   // `should_show_templates_ui_`.
@@ -129,6 +135,13 @@
       const std::vector<const DeskTemplate*>& new_entries);
   void RemoveUIEntries(const std::vector<std::string>& uuids);
 
+  // Returns a copy of a duplicated name to be stored.  This function works by
+  // taking the name to be duplicated and adding a "(1)" to it. If the name
+  // already has "(1)" then the number inside of the parenthesis will be
+  // incremented.
+  std::u16string AppendDuplicateNumberToDuplicateName(
+      const std::u16string& duplicate_name_u16);
+
   // Pointer to the session which owns `this`.
   OverviewSession* const overview_session_;
 
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc
index 3a8cd65..25c9633 100644
--- a/base/task/sequence_manager/task_queue_impl.cc
+++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -9,17 +9,14 @@
 #include <memory>
 #include <utility>
 
-#include "base/atomic_sequence_num.h"
 #include "base/check.h"
 #include "base/compiler_specific.h"
 #include "base/containers/stack_container.h"
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/observer_list.h"
-#include "base/rand_util.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/common/scoped_defer_task_posting.h"
@@ -525,7 +522,6 @@
     sequence_manager_->WillQueueTask(&pending_task, name_);
     MaybeReportIpcTaskQueuedFromMainThread(pending_task, name_);
   }
-  RecordTaskDelay(pending_task.delayed_run_time - lazy_now->Now());
   main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
   UpdateWakeUp(lazy_now);
 
@@ -574,18 +570,6 @@
   TraceQueueSize();
 }
 
-void TaskQueueImpl::RecordTaskDelay(TimeDelta delay) {
-  // This logic minimizes the performance overhead of emitting a histogram.
-  static AtomicSequenceNumber sample_id_;
-  static constexpr int kBatchSize = 10000;
-  static const int kOffset = RandInt(0, kBatchSize - 1);
-
-  if ((sample_id_.GetNext() - kOffset) % kBatchSize == 0) {
-    UMA_HISTOGRAM_LONG_TIMES("Scheduler.TaskQueueImpl.PostDelayedTaskDelay",
-                             delay);
-  }
-}
-
 void TaskQueueImpl::ReloadEmptyImmediateWorkQueue() {
   DCHECK(main_thread_only().immediate_work_queue->Empty());
   main_thread_only().immediate_work_queue->TakeImmediateIncomingQueueTasks();
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h
index 418547c..ad03f59 100644
--- a/base/task/sequence_manager/task_queue_impl.h
+++ b/base/task/sequence_manager/task_queue_impl.h
@@ -501,11 +501,6 @@
   void MoveReadyImmediateTasksToImmediateWorkQueueLocked()
       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
 
-  // Records the delay for some tasks in the main thread pseudorandomly in a
-  // histogram. The |delay| will be different than the delay passed to
-  // PostDelayedTask for cross-thread delayed tasks.
-  void RecordTaskDelay(TimeDelta delay);
-
   // LazilyDeallocatedDeque use TimeTicks to figure out when to resize.  We
   // should use real time here always.
   using TaskDeque =
diff --git a/base/win/embedded_i18n/language_selector.cc b/base/win/embedded_i18n/language_selector.cc
index 57e95ab..d8a456d 100644
--- a/base/win/embedded_i18n/language_selector.cc
+++ b/base/win/embedded_i18n/language_selector.cc
@@ -260,7 +260,7 @@
 void SelectLanguageMatchingCandidate(
     const std::vector<std::wstring>& candidates,
     span<const LangToOffset> languages_to_offset,
-    int* selected_offset,
+    size_t* selected_offset,
     std::wstring* matched_candidate,
     std::wstring* selected_language) {
   DCHECK(selected_offset);
@@ -306,7 +306,7 @@
     WStringPiece preferred_language) {
   std::vector<std::wstring> candidates;
 
-  // Get the intitial candidate list for this particular implementation (if
+  // Get the initial candidate list for this particular implementation (if
   // applicable).
   if (!preferred_language.empty())
     candidates.emplace_back(preferred_language);
diff --git a/base/win/embedded_i18n/language_selector.h b/base/win/embedded_i18n/language_selector.h
index 9be6f94..877730b 100644
--- a/base/win/embedded_i18n/language_selector.h
+++ b/base/win/embedded_i18n/language_selector.h
@@ -25,7 +25,7 @@
 // override selection should a corresponding translation be available.
 class BASE_EXPORT LanguageSelector {
  public:
-  using LangToOffset = std::pair<WStringPiece, int>;
+  using LangToOffset = std::pair<WStringPiece, size_t>;
 
   // Constructor to be used for users of this class that will provide the actual
   // language offsets that will be used.
@@ -53,7 +53,7 @@
   ~LanguageSelector();
 
   // The offset of the matched language (i.e., IDS_L10N_OFFSET_*).
-  int offset() const { return selected_offset_; }
+  size_t offset() const { return selected_offset_; }
 
   // The full name of the candidate language for which a match was found.
   const std::wstring& matched_candidate() const { return matched_candidate_; }
@@ -66,7 +66,7 @@
  private:
   std::wstring matched_candidate_;
   std::wstring selected_language_;
-  int selected_offset_;
+  size_t selected_offset_;
 };
 
 }  // namespace i18n
diff --git a/base/win/event_trace_controller.cc b/base/win/event_trace_controller.cc
index 937c00b..d50a3f8ae 100644
--- a/base/win/event_trace_controller.cc
+++ b/base/win/event_trace_controller.cc
@@ -3,8 +3,11 @@
 // found in the LICENSE file.
 //
 // Implementation of a Windows event trace controller class.
+
 #include "base/win/event_trace_controller.h"
+
 #include "base/check.h"
+#include "base/numerics/checked_math.h"
 
 constexpr size_t kDefaultRealtimeBufferSizeKb = 16;
 
@@ -88,7 +91,8 @@
   EVENT_TRACE_PROPERTIES& p = *prop.get();
   p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY;
   p.FlushTimer = 1;   // flush every second.
-  p.BufferSize = buffer_size ? buffer_size : kDefaultRealtimeBufferSizeKb;
+  p.BufferSize = checked_cast<ULONG>(
+      buffer_size ? buffer_size : kDefaultRealtimeBufferSizeKb);
   p.LogFileNameOffset = 0;
   return Start(session_name, &prop);
 }
diff --git a/base/win/patch_util.cc b/base/win/patch_util.cc
index 46c1a574..072d494 100644
--- a/base/win/patch_util.cc
+++ b/base/win/patch_util.cc
@@ -10,7 +10,7 @@
 namespace win {
 namespace internal {
 
-DWORD ModifyCode(void* destination, const void* source, int length) {
+DWORD ModifyCode(void* destination, const void* source, size_t length) {
   if ((nullptr == destination) || (nullptr == source) || (0 == length)) {
     NOTREACHED();
     return ERROR_INVALID_PARAMETER;
diff --git a/base/win/patch_util.h b/base/win/patch_util.h
index 9da88c9..c6ffb1c6 100644
--- a/base/win/patch_util.h
+++ b/base/win/patch_util.h
@@ -16,7 +16,9 @@
 // Copies |length| bytes from |source| to |destination|, temporarily setting
 // |destination| to writable. Returns a Windows error code or NO_ERROR if
 // successful.
-BASE_EXPORT DWORD ModifyCode(void* destination, const void* source, int length);
+BASE_EXPORT DWORD ModifyCode(void* destination,
+                             const void* source,
+                             size_t length);
 
 }  // namespace internal
 }  // namespace win
diff --git a/base/win/pe_image_reader.cc b/base/win/pe_image_reader.cc
index cefd0c73..c4cdc4aa 100644
--- a/base/win/pe_image_reader.cc
+++ b/base/win/pe_image_reader.cc
@@ -180,7 +180,7 @@
             win_certificate->dwLength - kWinCertificateSize, context)) {
       return false;
     }
-    size_t padded_length = (win_certificate->dwLength + 7) & ~0x7;
+    size_t padded_length = (win_certificate->dwLength + 7) & ~0x7u;
     // Don't overflow when recalculating data_size, since padded_length can be
     // attacker controlled.
     if (!CheckSub(data_size, padded_length).AssignIfValid(&data_size))
@@ -214,7 +214,8 @@
 
 bool PeImageReader::ValidatePeSignature() {
   const DWORD* signature = nullptr;
-  if (!GetStructureAt(GetDosHeader()->e_lfanew, &signature) ||
+  if (!GetStructureAt(static_cast<size_t>(GetDosHeader()->e_lfanew),
+                      &signature) ||
       *signature != IMAGE_NT_SIGNATURE) {
     return false;
   }
@@ -226,9 +227,9 @@
 bool PeImageReader::ValidateCoffFileHeader() {
   DCHECK_NE((validation_state_ & VALID_PE_SIGNATURE), 0U);
   const IMAGE_FILE_HEADER* file_header = nullptr;
-  if (!GetStructureAt(
-          GetDosHeader()->e_lfanew + offsetof(IMAGE_NT_HEADERS32, FileHeader),
-          &file_header)) {
+  if (!GetStructureAt(static_cast<size_t>(GetDosHeader()->e_lfanew) +
+                          offsetof(IMAGE_NT_HEADERS32, FileHeader),
+                      &file_header)) {
     return false;
   }
 
@@ -239,7 +240,8 @@
 bool PeImageReader::ValidateOptionalHeader() {
   const IMAGE_FILE_HEADER* file_header = GetCoffFileHeader();
   const size_t optional_header_offset =
-      GetDosHeader()->e_lfanew + offsetof(IMAGE_NT_HEADERS32, OptionalHeader);
+      static_cast<size_t>(GetDosHeader()->e_lfanew) +
+      offsetof(IMAGE_NT_HEADERS32, OptionalHeader);
   const size_t optional_header_size = file_header->SizeOfOptionalHeader;
   const WORD* optional_header_magic = nullptr;
 
@@ -287,7 +289,7 @@
   const size_t number_of_sections = GetNumberOfSections();
 
   // Do all section headers fit in the image?
-  if (!GetStructureAt(first_section_header - image_data_,
+  if (!GetStructureAt(static_cast<size_t>(first_section_header - image_data_),
                       number_of_sections * sizeof(IMAGE_SECTION_HEADER),
                       &first_section_header)) {
     return false;
diff --git a/base/win/registry.cc b/base/win/registry.cc
index db771c6..6b535aa 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -32,7 +32,7 @@
 // RegEnumValue() reports the number of characters from the name that were
 // written to the buffer, not how many there are. This constant is the maximum
 // name size, such that a buffer with this size should read any name.
-const DWORD MAX_REGISTRY_NAME_SIZE = 16384;
+constexpr DWORD MAX_REGISTRY_NAME_SIZE = 16384;
 
 // Registry values are read as BYTE* but can have wchar_t* data whose last
 // wchar_t is truncated. This function converts the reported |byte_size| to
@@ -42,7 +42,9 @@
 }
 
 // Mask to pull WOW64 access flags out of REGSAM access.
-const REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY;
+constexpr REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY;
+
+constexpr DWORD kInvalidIterValue = static_cast<DWORD>(-1);
 
 }  // namespace
 
@@ -257,7 +259,7 @@
   return (result == ERROR_SUCCESS) ? count : 0;
 }
 
-LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
+LONG RegKey::GetValueNameAt(DWORD index, std::wstring* name) const {
   wchar_t buf[256];
   DWORD bufsize = std::size(buf);
   LONG r = ::RegEnumValue(key_, index, buf, &bufsize, nullptr, nullptr, nullptr,
@@ -564,11 +566,12 @@
 }
 
 bool RegistryValueIterator::Valid() const {
-  return key_ != nullptr && index_ >= 0;
+  return key_ != nullptr && index_ != kInvalidIterValue;
 }
 
 void RegistryValueIterator::operator++() {
-  --index_;
+  if (index_ != kInvalidIterValue)
+    --index_;
   Read();
 }
 
@@ -642,11 +645,12 @@
 }
 
 bool RegistryKeyIterator::Valid() const {
-  return key_ != nullptr && index_ >= 0;
+  return key_ != nullptr && index_ != kInvalidIterValue;
 }
 
 void RegistryKeyIterator::operator++() {
-  --index_;
+  if (index_ != kInvalidIterValue)
+    --index_;
   Read();
 }
 
diff --git a/base/win/registry.h b/base/win/registry.h
index b812cbd..00a7f90 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -77,7 +77,7 @@
   DWORD GetValueCount() const;
 
   // Determines the nth value's name.
-  LONG GetValueNameAt(int index, std::wstring* name) const;
+  LONG GetValueNameAt(DWORD index, std::wstring* name) const;
 
   // True while the key is valid.
   bool Valid() const { return key_ != nullptr; }
@@ -187,7 +187,7 @@
   DWORD ValueSize() const { return value_size_; }
   DWORD Type() const { return type_; }
 
-  int Index() const { return index_; }
+  DWORD Index() const { return index_; }
 
  private:
   // Reads in the current values.
@@ -199,7 +199,7 @@
   HKEY key_;
 
   // Current index of the iteration.
-  int index_;
+  DWORD index_;
 
   // Current values.
   std::wstring name_;
@@ -237,7 +237,7 @@
 
   const wchar_t* Name() const { return name_; }
 
-  int Index() const { return index_; }
+  DWORD Index() const { return index_; }
 
  private:
   // Reads in the current values.
@@ -249,7 +249,7 @@
   HKEY key_;
 
   // Current index of the iteration.
-  int index_;
+  DWORD index_;
 
   wchar_t name_[MAX_PATH];
 };
diff --git a/base/win/security_util.cc b/base/win/security_util.cc
index 3d37aea..f4253532 100644
--- a/base/win/security_util.cc
+++ b/base/win/security_util.cc
@@ -12,6 +12,7 @@
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/numerics/checked_math.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_localalloc.h"
 #include "base/win/win_util.h"
@@ -53,8 +54,8 @@
   }
 
   PACL new_dacl = nullptr;
-  error = ::SetEntriesInAcl(access_entries.size(), access_entries.data(), dacl,
-                            &new_dacl);
+  error = ::SetEntriesInAcl(checked_cast<ULONG>(access_entries.size()),
+                            access_entries.data(), dacl, &new_dacl);
   if (error != ERROR_SUCCESS) {
     ::SetLastError(error);
     DPLOG(ERROR) << "Failed adding ACEs to DACL for path \"" << path.value()
diff --git a/base/win/shortcut.h b/base/win/shortcut.h
index db0ecf9..646f217 100644
--- a/base/win/shortcut.h
+++ b/base/win/shortcut.h
@@ -31,21 +31,21 @@
 // Callers are encouraged to use the setters provided which take care of
 // setting |options| as desired.
 struct BASE_EXPORT ShortcutProperties {
-  enum IndividualProperties {
-    PROPERTIES_TARGET = 1U << 0,
-    PROPERTIES_WORKING_DIR = 1U << 1,
-    PROPERTIES_ARGUMENTS = 1U << 2,
-    PROPERTIES_DESCRIPTION = 1U << 3,
-    PROPERTIES_ICON = 1U << 4,
-    PROPERTIES_APP_ID = 1U << 5,
-    PROPERTIES_DUAL_MODE = 1U << 6,
-    PROPERTIES_TOAST_ACTIVATOR_CLSID = 1U << 7,
-    // Be sure to update the values below when adding a new property.
-    PROPERTIES_ALL = PROPERTIES_TARGET | PROPERTIES_WORKING_DIR |
-                     PROPERTIES_ARGUMENTS | PROPERTIES_DESCRIPTION |
-                     PROPERTIES_ICON | PROPERTIES_APP_ID |
-                     PROPERTIES_DUAL_MODE | PROPERTIES_TOAST_ACTIVATOR_CLSID
-  };
+  using IndividualProperties = uint32_t;
+  static constexpr IndividualProperties PROPERTIES_TARGET = 1U << 0;
+  static constexpr IndividualProperties PROPERTIES_WORKING_DIR = 1U << 1;
+  static constexpr IndividualProperties PROPERTIES_ARGUMENTS = 1U << 2;
+  static constexpr IndividualProperties PROPERTIES_DESCRIPTION = 1U << 3;
+  static constexpr IndividualProperties PROPERTIES_ICON = 1U << 4;
+  static constexpr IndividualProperties PROPERTIES_APP_ID = 1U << 5;
+  static constexpr IndividualProperties PROPERTIES_DUAL_MODE = 1U << 6;
+  static constexpr IndividualProperties PROPERTIES_TOAST_ACTIVATOR_CLSID = 1U
+                                                                           << 7;
+  // Be sure to update the values below when adding a new property.
+  static constexpr IndividualProperties PROPERTIES_ALL =
+      PROPERTIES_TARGET | PROPERTIES_WORKING_DIR | PROPERTIES_ARGUMENTS |
+      PROPERTIES_DESCRIPTION | PROPERTIES_ICON | PROPERTIES_APP_ID |
+      PROPERTIES_DUAL_MODE | PROPERTIES_TOAST_ACTIVATOR_CLSID;
 
   ShortcutProperties();
   ShortcutProperties(const ShortcutProperties& other);
diff --git a/base/win/variant_vector.cc b/base/win/variant_vector.cc
index 6e5e6fea..a06f2bd 100644
--- a/base/win/variant_vector.cc
+++ b/base/win/variant_vector.cc
@@ -6,6 +6,7 @@
 
 #include "base/check_op.h"
 #include "base/notreached.h"
+#include "base/numerics/checked_math.h"
 #include "base/process/memory.h"
 #include "base/win/scoped_safearray.h"
 #include "base/win/scoped_variant.h"
@@ -320,7 +321,7 @@
   DCHECK(!Empty());
 
   ScopedSafearray scoped_safearray(
-      SafeArrayCreateVector(ElementVartype, 0, Size()));
+      SafeArrayCreateVector(ElementVartype, 0, checked_cast<ULONG>(Size())));
   if (!scoped_safearray.Get()) {
     constexpr size_t kElementSize =
         sizeof(typename internal::VariantUtil<ElementVartype>::Type);
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index dfb78ed..a5c20144 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -703,7 +703,8 @@
     size_t num_modules = bytes_required / sizeof(HMODULE);
     if (num_modules <= snapshot->size()) {
       // Buffer size was too big, presumably because a module was unloaded.
-      snapshot->erase(snapshot->begin() + num_modules, snapshot->end());
+      snapshot->erase(snapshot->begin() + static_cast<ptrdiff_t>(num_modules),
+                      snapshot->end());
       return true;
     } else if (num_modules == 0) {
       DLOG(ERROR) << "Can't determine the module list size.";
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index 7896143..a72b8a4a 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -125,7 +125,7 @@
 
 OSInfo::OSInfo(const _OSVERSIONINFOEXW& version_info,
                const _SYSTEM_INFO& system_info,
-               int os_type)
+               DWORD os_type)
     : version_(Version::PRE_XP),
       wow_process_machine_(WowProcessMachine::kUnknown),
       wow_native_machine_(WowNativeMachine::kUnknown) {
@@ -140,7 +140,7 @@
   service_pack_.minor = version_info.wServicePackMinor;
   service_pack_str_ = WideToUTF8(version_info.szCSDVersion);
 
-  processors_ = system_info.dwNumberOfProcessors;
+  processors_ = static_cast<int>(system_info.dwNumberOfProcessors);
   allocation_granularity_ = system_info.dwAllocationGranularity;
 
   if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) {
diff --git a/base/win/windows_version.h b/base/win/windows_version.h
index 01fe778..b704c52 100644
--- a/base/win/windows_version.h
+++ b/base/win/windows_version.h
@@ -13,6 +13,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/version.h"
 
+using DWORD = unsigned long;  // NOLINT(runtime/int)
 using HANDLE = void*;
 struct _OSVERSIONINFOEXW;
 struct _SYSTEM_INFO;
@@ -183,7 +184,7 @@
 
   OSInfo(const _OSVERSIONINFOEXW& version_info,
          const _SYSTEM_INFO& system_info,
-         int os_type);
+         DWORD os_type);
   ~OSInfo();
 
   // Returns a Version value for a given OS version tuple.
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index aedf047c..8a95579 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220606.1.1
+8.20220606.2.1
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 516dc9d..7b8bfa3 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1468,12 +1468,10 @@
   const auto& inputs = inputs_.Read(*this);
   layer->SetElementId(inputs.element_id);
   layer->SetHasTransformNode(has_transform_node());
-  // TODO(crbug/1308932): Remove toSkColor and FromColor and make all SkColor4f.
-  layer->SetBackgroundColor(inputs.background_color.toSkColor());
-  layer->SetSafeOpaqueBackgroundColor(
-      SafeOpaqueBackgroundColor(
-          SkColor4f::FromColor(commit_state.background_color))
-          .toSkColor());
+  layer->SetBackgroundColor(inputs.background_color);
+  // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
+  layer->SetSafeOpaqueBackgroundColor(SafeOpaqueBackgroundColor(
+      SkColor4f::FromColor(commit_state.background_color)));
   layer->SetBounds(inputs.bounds);
   layer->SetTransformTreeIndex(transform_tree_index(property_trees));
   layer->SetEffectTreeIndex(effect_tree_index(property_trees));
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 0612288..1e9e856c 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -71,8 +71,8 @@
       contributes_to_drawn_render_surface_(false),
       hit_testable_(false),
       is_inner_viewport_scroll_layer_(false),
-      background_color_(0),
-      safe_opaque_background_color_(0),
+      background_color_(SkColors::kTransparent),
+      safe_opaque_background_color_(SkColors::kTransparent),
       transform_tree_index_(kInvalidPropertyNodeId),
       effect_tree_index_(kInvalidPropertyNodeId),
       clip_tree_index_(kInvalidPropertyNodeId),
@@ -228,19 +228,17 @@
   return layer_tree_impl()->debug_state().show_debug_borders.test(type);
 }
 
-void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
+void LayerImpl::GetDebugBorderProperties(SkColor4f* color, float* width) const {
   float device_scale_factor =
       layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
 
   if (draws_content_) {
-    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-    *color = DebugColors::ContentLayerBorderColor().toSkColor();
+    *color = DebugColors::ContentLayerBorderColor();
     *width = DebugColors::ContentLayerBorderWidth(device_scale_factor);
     return;
   }
 
-  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-  *color = DebugColors::ContainerLayerBorderColor().toSkColor();
+  *color = DebugColors::ContainerLayerBorderColor();
   *width = DebugColors::ContainerLayerBorderWidth(device_scale_factor);
 }
 
@@ -249,7 +247,7 @@
     const gfx::Rect& quad_rect,
     const viz::SharedQuadState* shared_quad_state,
     AppendQuadsData* append_quads_data) const {
-  SkColor color;
+  SkColor4f color;
   float width;
   GetDebugBorderProperties(&color, &width);
   AppendDebugBorderQuad(render_pass, quad_rect, shared_quad_state,
@@ -261,7 +259,7 @@
     const gfx::Rect& quad_rect,
     const viz::SharedQuadState* shared_quad_state,
     AppendQuadsData* append_quads_data,
-    SkColor color,
+    SkColor4f color,
     float width) const {
   if (!ShowDebugBorders(DebugBorderType::LAYER))
     return;
@@ -275,14 +273,15 @@
   gfx::Rect visible_quad_rect(quad_rect);
   auto* debug_border_quad =
       render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
-  debug_border_quad->SetNew(
-      shared_quad_state, quad_rect, visible_quad_rect, color, width);
+  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+  debug_border_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
+                            color.toSkColor(), width);
   if (contents_opaque()) {
     // When opaque, draw a second inner border that is thicker than the outer
     // border, but more transparent.
     static const float kFillOpacity = 0.3f;
-    SkColor fill_color = SkColorSetA(
-        color, static_cast<uint8_t>(SkColorGetA(color) * kFillOpacity));
+    SkColor4f fill_color = color;
+    color.fA *= kFillOpacity;
     float fill_width = width * 3;
     gfx::Rect fill_rect = quad_rect;
     fill_rect.Inset(fill_width / 2.f);
@@ -290,10 +289,11 @@
       return;
     gfx::Rect visible_fill_rect =
         gfx::IntersectRects(visible_quad_rect, fill_rect);
+    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
     auto* fill_quad =
         render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
     fill_quad->SetNew(shared_quad_state, fill_rect, visible_fill_rect,
-                      fill_color, fill_width);
+                      fill_color.toSkColor(), fill_width);
   }
 }
 
@@ -571,7 +571,7 @@
   return should_hit_test;
 }
 
-void LayerImpl::SetBackgroundColor(SkColor background_color) {
+void LayerImpl::SetBackgroundColor(SkColor4f background_color) {
   if (background_color_ == background_color)
     return;
 
@@ -579,7 +579,7 @@
   NoteLayerPropertyChanged();
 }
 
-void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor background_color) {
+void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor4f background_color) {
   safe_opaque_background_color_ = background_color;
 }
 
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 8777e92c..a02b814 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -164,13 +164,12 @@
   void SetHitTestable(bool should_hit_test);
   bool HitTestable() const;
 
-  void SetBackgroundColor(SkColor background_color);
-  SkColor background_color() const { return background_color_; }
-  void SetSafeOpaqueBackgroundColor(SkColor background_color);
-  SkColor safe_opaque_background_color() const {
+  void SetBackgroundColor(SkColor4f background_color);
+  SkColor4f background_color() const { return background_color_; }
+  void SetSafeOpaqueBackgroundColor(SkColor4f background_color);
+  SkColor4f safe_opaque_background_color() const {
     // Layer::SafeOpaqueBackgroundColor() should ensure this.
-    DCHECK_EQ(contents_opaque(),
-              SkColorGetA(safe_opaque_background_color_) == SK_AlphaOPAQUE);
+    DCHECK_EQ(contents_opaque(), safe_opaque_background_color_.isOpaque());
     return safe_opaque_background_color_;
   }
 
@@ -471,7 +470,7 @@
             bool will_always_push_properties = false);
 
   // Get the color and size of the layer's debug border.
-  virtual void GetDebugBorderProperties(SkColor* color, float* width) const;
+  virtual void GetDebugBorderProperties(SkColor4f* color, float* width) const;
 
   void AppendDebugBorderQuad(viz::CompositorRenderPass* render_pass,
                              const gfx::Rect& quad_rect,
@@ -481,7 +480,7 @@
                              const gfx::Rect& quad_rect,
                              const viz::SharedQuadState* shared_quad_state,
                              AppendQuadsData* append_quads_data,
-                             SkColor color,
+                             SkColor4f color,
                              float width) const;
 
   static float GetPreferredRasterScale(
@@ -538,8 +537,8 @@
 
   TouchActionRegion touch_action_region_;
 
-  SkColor background_color_;
-  SkColor safe_opaque_background_color_;
+  SkColor4f background_color_;
+  SkColor4f safe_opaque_background_color_;
 
   int transform_tree_index_;
   int effect_tree_index_;
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc
index 73a0698f..095e57d 100644
--- a/cc/layers/layer_impl_unittest.cc
+++ b/cc/layers/layer_impl_unittest.cc
@@ -102,7 +102,7 @@
   gfx::Point arbitrary_point = gfx::Point(333, 444);
 
   gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
-  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
+  SkColor4f arbitrary_color{0.1f, 0.2f, 0.3f, 1.0f};
   gfx::Transform arbitrary_transform;
   arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
   FilterOperations arbitrary_filters;
@@ -166,7 +166,7 @@
   gfx::PointF arbitrary_scroll_offset(
       gfx::PointAtOffsetFromOrigin(arbitrary_vector2d));
   gfx::Size large_size = gfx::Size(1000, 1000);
-  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
+  SkColor4f arbitrary_color{0.1f, 0.2f, 0.3f, 1.0f};
   gfx::Transform arbitrary_transform;
   arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
   FilterOperations arbitrary_filters;
diff --git a/cc/layers/layer_perftest.cc b/cc/layers/layer_perftest.cc
index 4c419ecb..dba359c 100644
--- a/cc/layers/layer_perftest.cc
+++ b/cc/layers/layer_perftest.cc
@@ -125,7 +125,7 @@
   std::unique_ptr<LayerImpl> impl_layer =
       LayerImpl::Create(host_impl_.active_tree(), 2);
 
-  SkColor background_color = SK_ColorRED;
+  SkColor4f background_color = SkColors::kRed;
   gfx::Size bounds(1000, 1000);
   bool draws_content = true;
   bool contents_opaque = true;
@@ -142,7 +142,7 @@
     test_layer->PushPropertiesTo(impl_layer.get());
 
     background_color =
-        background_color == SK_ColorRED ? SK_ColorGREEN : SK_ColorRED;
+        background_color == SkColors::kRed ? SkColors::kGreen : SkColors::kRed;
     bounds = bounds == gfx::Size(1000, 1000) ? gfx::Size(500, 500)
                                              : gfx::Size(1000, 1000);
     draws_content = !draws_content;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 8993cc58..39e68be 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -230,9 +230,10 @@
     Occlusion occlusion = draw_properties().occlusion_in_content_space;
 
     EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
+    // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
     SolidColorLayerImpl::AppendSolidQuads(
         render_pass, occlusion, shared_quad_state, scaled_visible_layer_rect,
-        raster_source_->GetSolidColor(),
+        SkColor4f::FromColor(raster_source_->GetSolidColor()),
         !layer_tree_impl()->settings().enable_edge_anti_aliasing,
         effect_node->blend_mode, append_quads_data);
     return;
@@ -295,10 +296,9 @@
 
   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
     DCHECK(shared_quad_state->quad_layer_rect.origin() == gfx::Point(0, 0));
-    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
     AppendDebugBorderQuad(
         render_pass, shared_quad_state->quad_layer_rect, shared_quad_state,
-        append_quads_data, DebugColors::DirectPictureBorderColor().toSkColor(),
+        append_quads_data, DebugColors::DirectPictureBorderColor(),
         DebugColors::DirectPictureBorderWidth(device_scale_factor));
 
     gfx::Rect geometry_rect = shared_quad_state->visible_quad_layer_rect;
@@ -367,33 +367,31 @@
              shared_quad_state->visible_quad_layer_rect,
              ideal_contents_scale_key());
          iter; ++iter) {
-      SkColor color;
+      SkColor4f color;
       float width;
       if (*iter && iter->draw_info().IsReadyToDraw()) {
-        // TODO(crbug/1308932): Remove all instances of toSkColor below and make
-        // all SkColor4f.
         TileDrawInfo::Mode mode = iter->draw_info().mode();
         if (mode == TileDrawInfo::SOLID_COLOR_MODE) {
-          color = DebugColors::SolidColorTileBorderColor().toSkColor();
+          color = DebugColors::SolidColorTileBorderColor();
           width = DebugColors::SolidColorTileBorderWidth(device_scale_factor);
         } else if (mode == TileDrawInfo::OOM_MODE) {
-          color = DebugColors::OOMTileBorderColor().toSkColor();
+          color = DebugColors::OOMTileBorderColor();
           width = DebugColors::OOMTileBorderWidth(device_scale_factor);
         } else if (iter.resolution() == HIGH_RESOLUTION) {
-          color = DebugColors::HighResTileBorderColor().toSkColor();
+          color = DebugColors::HighResTileBorderColor();
           width = DebugColors::HighResTileBorderWidth(device_scale_factor);
         } else if (iter.resolution() == LOW_RESOLUTION) {
-          color = DebugColors::LowResTileBorderColor().toSkColor();
+          color = DebugColors::LowResTileBorderColor();
           width = DebugColors::LowResTileBorderWidth(device_scale_factor);
         } else if (iter->contents_scale_key() > max_contents_scale) {
-          color = DebugColors::ExtraHighResTileBorderColor().toSkColor();
+          color = DebugColors::ExtraHighResTileBorderColor();
           width = DebugColors::ExtraHighResTileBorderWidth(device_scale_factor);
         } else {
-          color = DebugColors::ExtraLowResTileBorderColor().toSkColor();
+          color = DebugColors::ExtraLowResTileBorderColor();
           width = DebugColors::ExtraLowResTileBorderWidth(device_scale_factor);
         }
       } else {
-        color = DebugColors::MissingTileBorderColor().toSkColor();
+        color = DebugColors::MissingTileBorderColor();
         width = DebugColors::MissingTileBorderWidth(device_scale_factor);
       }
 
@@ -402,10 +400,9 @@
       gfx::Rect geometry_rect = iter.geometry_rect();
       geometry_rect.Offset(quad_offset);
       gfx::Rect visible_geometry_rect = geometry_rect;
-      debug_border_quad->SetNew(shared_quad_state,
-                                geometry_rect,
-                                visible_geometry_rect,
-                                color,
+      // TODO(crbug/1308932): Remove  toSkColor  and make all SkColor4f.
+      debug_border_quad->SetNew(shared_quad_state, geometry_rect,
+                                visible_geometry_rect, color.toSkColor(),
                                 width);
     }
   }
@@ -518,16 +515,16 @@
 
     if (!has_draw_quad) {
       // Checkerboard.
-      SkColor color = safe_opaque_background_color();
+      SkColor4f color = safe_opaque_background_color();
       if (ShowDebugBorders(DebugBorderType::LAYER)) {
         // Fill the whole tile with the missing tile color.
-        // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-        color = DebugColors::DefaultCheckerboardColor().toSkColor();
+        color = DebugColors::DefaultCheckerboardColor();
       }
       auto* quad =
           render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+      // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
       quad->SetNew(shared_quad_state, offset_geometry_rect,
-                   offset_visible_geometry_rect, color, false);
+                   offset_visible_geometry_rect, color.toSkColor(), false);
       ValidateQuadResources(quad);
 
       if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
@@ -866,7 +863,7 @@
   if (!layer_tree_impl()->settings().can_use_lcd_text)
     return LCDTextDisallowedReason::kSetting;
   if (!contents_opaque_for_text()) {
-    if (SkColorGetA(background_color()) != SK_AlphaOPAQUE)
+    if (!background_color().isOpaque())
       return LCDTextDisallowedReason::kBackgroundColorNotOpaque;
     return LCDTextDisallowedReason::kContentsNotOpaque;
   }
@@ -1867,19 +1864,16 @@
                          ideal_contents_scale_.y() / ideal_page_scale_};
 }
 
-void PictureLayerImpl::GetDebugBorderProperties(
-    SkColor* color,
-    float* width) const {
+void PictureLayerImpl::GetDebugBorderProperties(SkColor4f* color,
+                                                float* width) const {
   float device_scale_factor =
       layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
 
   if (IsDirectlyCompositedImage()) {
-    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-    *color = DebugColors::ImageLayerBorderColor().toSkColor();
+    *color = DebugColors::ImageLayerBorderColor();
     *width = DebugColors::ImageLayerBorderWidth(device_scale_factor);
   } else {
-    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-    *color = DebugColors::TiledContentLayerBorderColor().toSkColor();
+    *color = DebugColors::TiledContentLayerBorderColor();
     *width = DebugColors::TiledContentLayerBorderWidth(device_scale_factor);
   }
 }
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index eaed334..23ca1f2 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -214,7 +214,7 @@
 
   void SanityCheckTilingState() const;
 
-  void GetDebugBorderProperties(SkColor* color, float* width) const override;
+  void GetDebugBorderProperties(SkColor4f* color, float* width) const override;
   void GetAllPrioritizedTilesForTracing(
       std::vector<PrioritizedTile>* prioritized_tiles) const override;
   void AsValueInto(base::trace_event::TracedValue* dict) const override;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 9284251..ba9a966 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -6280,7 +6280,7 @@
       FakeRasterSource::CreateFilledWithText(gfx::Size(200, 200));
   SetupTreesWithInvalidation(raster_source, raster_source, Region());
 
-  pending_layer()->SetBackgroundColor(SK_ColorWHITE);
+  pending_layer()->SetBackgroundColor(SkColors::kWhite);
   pending_layer()->SetContentsOpaque(true);
   pending_layer()->SetOffsetToTransformParent(gfx::Vector2dF(0.2, 0.3));
   host_impl()->pending_tree()->set_needs_update_draw_properties();
@@ -6336,7 +6336,7 @@
   auto raster_source = FakeRasterSource::CreateFilled(gfx::Size(200, 200));
   SetupTreesWithInvalidation(raster_source, raster_source, Region());
 
-  pending_layer()->SetBackgroundColor(SK_ColorWHITE);
+  pending_layer()->SetBackgroundColor(SkColors::kWhite);
   pending_layer()->SetContentsOpaque(true);
   pending_layer()->SetOffsetToTransformParent(gfx::Vector2dF(0.2, 0.3));
   host_impl()->pending_tree()->set_needs_update_draw_properties();
@@ -6540,14 +6540,14 @@
 TEST_P(LCDTextTest, ContentsNotOpaque) {
   // Non-opaque content and opaque background.
   layer_->SetContentsOpaque(false);
-  layer_->SetBackgroundColor(SK_ColorGREEN);
+  layer_->SetBackgroundColor(SkColors::kGreen);
   CheckCanUseLCDText(LCDTextDisallowedReason::kContentsNotOpaque,
                      "contents not opaque", layer_);
   CheckCanUseLCDText(LCDTextDisallowedReason::kNone,
                      "descedant of contents not opaque", descendant_);
 
   // Non-opaque content and non-opaque background.
-  layer_->SetBackgroundColor(SkColorSetARGB(128, 255, 255, 255));
+  layer_->SetBackgroundColor({1.0f, 1.0f, 1.0f, 0.5f});
   CheckCanUseLCDText(LCDTextDisallowedReason::kBackgroundColorNotOpaque,
                      "background not opaque", layer_);
   CheckCanUseLCDText(LCDTextDisallowedReason::kNone,
@@ -6635,7 +6635,7 @@
 
 TEST_P(LCDTextTest, ContentsOpaqueForText) {
   layer_->SetContentsOpaque(false);
-  layer_->SetBackgroundColor(SK_ColorGREEN);
+  layer_->SetBackgroundColor(SkColors::kGreen);
   layer_->SetContentsOpaqueForText(true);
   CheckCanUseLCDText(LCDTextDisallowedReason::kNone, "contents opaque for text",
                      layer_);
diff --git a/cc/layers/solid_color_layer_impl.cc b/cc/layers/solid_color_layer_impl.cc
index 9baa31ce..7e6332c 100644
--- a/cc/layers/solid_color_layer_impl.cc
+++ b/cc/layers/solid_color_layer_impl.cc
@@ -31,7 +31,7 @@
     const Occlusion& occlusion_in_layer_space,
     viz::SharedQuadState* shared_quad_state,
     const gfx::Rect& visible_layer_rect,
-    SkColor color,
+    SkColor4f color,
     bool force_anti_aliasing_off,
     SkBlendMode effect_blend_mode,
     AppendQuadsData* append_quads_data) {
@@ -45,8 +45,7 @@
   // mask, but will not work in complex blend mode situations. This bug is
   // tracked in crbug.com/939168.
   if (effect_blend_mode == SkBlendMode::kSrcOver) {
-    float alpha =
-        (SkColorGetA(color) * (1.0f / 255.0f)) * shared_quad_state->opacity;
+    float alpha = color.fA * shared_quad_state->opacity;
 
     if (alpha < std::numeric_limits<float>::epsilon())
       return;
@@ -58,8 +57,9 @@
     return;
 
   auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
-  quad->SetNew(shared_quad_state, visible_layer_rect, visible_quad_rect, color,
-               force_anti_aliasing_off);
+  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
+  quad->SetNew(shared_quad_state, visible_layer_rect, visible_quad_rect,
+               color.toSkColor(), force_anti_aliasing_off);
 }
 
 void SolidColorLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
diff --git a/cc/layers/solid_color_layer_impl.h b/cc/layers/solid_color_layer_impl.h
index 2090424..321e6b2 100644
--- a/cc/layers/solid_color_layer_impl.h
+++ b/cc/layers/solid_color_layer_impl.h
@@ -27,7 +27,7 @@
                                const Occlusion& occlusion_in_layer_space,
                                viz::SharedQuadState* shared_quad_state,
                                const gfx::Rect& visible_layer_rect,
-                               SkColor color,
+                               SkColor4f color,
                                bool force_anti_aliasing_off,
                                SkBlendMode effect_blend_mode,
                                AppendQuadsData* append_quads_data);
diff --git a/cc/layers/solid_color_layer_impl_unittest.cc b/cc/layers/solid_color_layer_impl_unittest.cc
index bae4ed23..efee583 100644
--- a/cc/layers/solid_color_layer_impl_unittest.cc
+++ b/cc/layers/solid_color_layer_impl_unittest.cc
@@ -33,7 +33,7 @@
   auto* layer = AddLayer<SolidColorLayerImpl>();
   layer->SetBounds(layer_size);
   layer->SetDrawsContent(true);
-  layer->SetBackgroundColor(SK_ColorRED);
+  layer->SetBackgroundColor(SkColors::kRed);
   CopyProperties(root_layer(), layer);
   CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest;
   UpdateActiveTreeDrawProperties();
@@ -44,7 +44,7 @@
 }
 
 TEST_F(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) {
-  SkColor test_color = 0xFFA55AFF;
+  SkColor4f test_color{0.647058f, 0.352941f, 1.0f, 1.0f};
   auto render_pass = viz::CompositorRenderPass::Create();
   gfx::Size layer_size = gfx::Size(100, 100);
   gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
@@ -64,10 +64,11 @@
   layer->AppendQuads(render_pass.get(), &data);
 
   ASSERT_EQ(render_pass->quad_list.size(), 1U);
+  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
   EXPECT_EQ(
       viz::SolidColorDrawQuad::MaterialCast(render_pass->quad_list.front())
           ->color,
-      test_color);
+      test_color.toSkColor());
 }
 
 TEST_F(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) {
@@ -78,7 +79,7 @@
   auto* layer = AddLayer<SolidColorLayerImpl>();
   layer->SetDrawsContent(true);
   layer->SetBounds(layer_size);
-  layer->SetBackgroundColor(SK_ColorRED);
+  layer->SetBackgroundColor(SkColors::kRed);
   CopyProperties(root_layer(), layer);
   auto& effect_node = CreateEffectNode(layer);
   effect_node.opacity = opacity;
@@ -104,7 +105,7 @@
   auto* layer = AddLayer<SolidColorLayerImpl>();
   layer->SetDrawsContent(true);
   layer->SetBounds(layer_size);
-  layer->SetBackgroundColor(SK_ColorRED);
+  layer->SetBackgroundColor(SkColors::kRed);
   CopyProperties(root_layer(), layer);
   auto& effect_node = CreateEffectNode(layer);
   effect_node.render_surface_reason = RenderSurfaceReason::kTest;
@@ -126,7 +127,7 @@
 }
 
 TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentAlpha) {
-  SkColor test_color = 0;
+  SkColor4f test_color = SkColors::kTransparent;
   auto render_pass = viz::CompositorRenderPass::Create();
   gfx::Size layer_size = gfx::Size(100, 100);
 
@@ -144,7 +145,7 @@
 }
 
 TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentOpacity) {
-  SkColor test_color = 0xFFA55AFF;
+  SkColor4f test_color{0.5f, 0.8f, 1.0f, 1.0f};
   auto render_pass = viz::CompositorRenderPass::Create();
   gfx::Size layer_size = gfx::Size(100, 100);
 
@@ -260,7 +261,7 @@
   gfx::Size viewport_size(1000, 1000);
 
   auto* solid_color_layer_impl = AddLayer<SolidColorLayerImpl>();
-  solid_color_layer_impl->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30));
+  solid_color_layer_impl->SetBackgroundColor({0.1f, 0.2f, 0.3f, 1.0f});
   solid_color_layer_impl->SetBounds(layer_size);
   solid_color_layer_impl->SetDrawsContent(true);
   CopyProperties(root_layer(), solid_color_layer_impl);
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc
index 4739957..c305048 100644
--- a/cc/layers/surface_layer_impl.cc
+++ b/cc/layers/surface_layer_impl.cc
@@ -182,8 +182,9 @@
 
   if (surface_range_.IsValid()) {
     auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
+    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
     quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
-                 surface_range_, background_color(),
+                 surface_range_, background_color().toSkColor(),
                  stretch_content_to_fill_bounds_);
     quad->is_reflection = is_reflection_;
     // Add the primary surface ID as a dependency.
@@ -199,8 +200,10 @@
   } else {
     auto* quad =
         render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+    // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
     quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
-                 background_color(), false /* force_anti_aliasing_off */);
+                 background_color().toSkColor(),
+                 false /* force_anti_aliasing_off */);
   }
 
   // Unless the client explicitly specifies otherwise, don't block on
@@ -217,10 +220,9 @@
       layer_tree_impl()->device_scale_factor());
 }
 
-void SurfaceLayerImpl::GetDebugBorderProperties(SkColor* color,
+void SurfaceLayerImpl::GetDebugBorderProperties(SkColor4f* color,
                                                 float* width) const {
-  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
-  *color = DebugColors::SurfaceLayerBorderColor().toSkColor();
+  *color = DebugColors::SurfaceLayerBorderColor();
   *width = DebugColors::SurfaceLayerBorderWidth(
       layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1);
 }
@@ -234,7 +236,7 @@
       render_pass->CreateAndAppendSharedQuadState();
   PopulateSharedQuadState(shared_quad_state, contents_opaque());
 
-  SkColor color;
+  SkColor4f color;
   float border_width;
   GetDebugBorderProperties(&color, &border_width);
 
diff --git a/cc/layers/surface_layer_impl.h b/cc/layers/surface_layer_impl.h
index 12174b6..936028b 100644
--- a/cc/layers/surface_layer_impl.h
+++ b/cc/layers/surface_layer_impl.h
@@ -75,7 +75,7 @@
   SurfaceLayerImpl(LayerTreeImpl* tree_impl, int id, UpdateSubmissionStateCB);
 
  private:
-  void GetDebugBorderProperties(SkColor* color, float* width) const override;
+  void GetDebugBorderProperties(SkColor4f* color, float* width) const override;
   void AppendRainbowDebugBorder(viz::CompositorRenderPass* render_pass);
   void AsValueInto(base::trace_event::TracedValue* dict) const override;
   const char* LayerTypeAsString() const override;
diff --git a/cc/layers/surface_layer_impl_unittest.cc b/cc/layers/surface_layer_impl_unittest.cc
index dae8486..5c263bd 100644
--- a/cc/layers/surface_layer_impl_unittest.cc
+++ b/cc/layers/surface_layer_impl_unittest.cc
@@ -97,7 +97,7 @@
   surface_layer_impl->SetBounds(layer_size);
   surface_layer_impl->SetDrawsContent(true);
   surface_layer_impl->SetRange(viz::SurfaceRange(surface_id2, surface_id1), 2u);
-  surface_layer_impl->SetBackgroundColor(SK_ColorBLUE);
+  surface_layer_impl->SetBackgroundColor(SkColors::kBlue);
   CopyProperties(impl.root_layer(), surface_layer_impl);
 
   gfx::Size viewport_size(1000, 1000);
@@ -235,7 +235,7 @@
   surface_layer_impl->SetDrawsContent(true);
   surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 1u);
   surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 2u);
-  surface_layer_impl->SetBackgroundColor(SK_ColorBLUE);
+  surface_layer_impl->SetBackgroundColor(SkColors::kBlue);
   CopyProperties(impl.root_layer(), surface_layer_impl);
 
   gfx::Size viewport_size(1000, 1000);
diff --git a/cc/layers/surface_layer_unittest.cc b/cc/layers/surface_layer_unittest.cc
index e43ee7f..f70a2747 100644
--- a/cc/layers/surface_layer_unittest.cc
+++ b/cc/layers/surface_layer_unittest.cc
@@ -166,7 +166,7 @@
   // Verify that the primary and fallback SurfaceIds are pushed through.
   EXPECT_EQ(primary_id, layer_impl->range().end());
   EXPECT_EQ(primary_id, layer_impl->range().start());
-  EXPECT_EQ(SK_ColorBLUE, layer_impl->background_color());
+  EXPECT_EQ(SkColors::kBlue, layer_impl->background_color());
   EXPECT_TRUE(layer_impl->stretch_content_to_fill_bounds());
   EXPECT_EQ(2u, layer_impl->deadline_in_frames());
 
@@ -193,7 +193,7 @@
   // fallback viz::SurfaceId is pushed through.
   EXPECT_EQ(fallback_id, layer_impl->range().end());
   EXPECT_EQ(fallback_id, layer_impl->range().start());
-  EXPECT_EQ(SK_ColorGREEN, layer_impl->background_color());
+  EXPECT_EQ(SkColors::kGreen, layer_impl->background_color());
   // The deadline resets back to 0 (no deadline) after the first commit.
   EXPECT_EQ(0u, layer_impl->deadline_in_frames());
   EXPECT_FALSE(layer_impl->stretch_content_to_fill_bounds());
diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc
index 8b9bf91e..a41414db 100644
--- a/cc/layers/texture_layer_impl.cc
+++ b/cc/layers/texture_layer_impl.cc
@@ -122,15 +122,14 @@
       std::make_move_iterator(to_register_bitmaps_.end()));
   to_register_bitmaps_.clear();
 
-  SkColor bg_color =
-      blend_background_color_ ? background_color() : SK_ColorTRANSPARENT;
+  SkColor4f bg_color =
+      blend_background_color_ ? background_color() : SkColors::kTransparent;
 
   if (force_texture_to_opaque_) {
-    bg_color = SK_ColorBLACK;
+    bg_color = SkColors::kBlack;
   }
 
-  bool are_contents_opaque =
-      contents_opaque() || (SkColorGetA(bg_color) == 0xFF);
+  bool are_contents_opaque = contents_opaque() || bg_color.isOpaque();
 
   viz::SharedQuadState* shared_quad_state =
       render_pass->CreateAndAppendSharedQuadState();
@@ -148,11 +147,12 @@
     return;
 
   float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
+  // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
   auto* quad = render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
   quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, needs_blending,
                resource_id_, premultiplied_alpha_, uv_top_left_,
-               uv_bottom_right_, bg_color, vertex_opacity, flipped_,
-               nearest_neighbor_, /*secure_output_only=*/false,
+               uv_bottom_right_, bg_color.toSkColor(), vertex_opacity, flipped_,
+               nearest_neighbor_, /*secure_output=*/false,
                gfx::ProtectedVideoType::kClear);
   quad->set_resource_size_in_pixels(transferable_resource_.size);
   ValidateQuadResources(quad);
@@ -165,7 +165,7 @@
   if (force_texture_to_opaque_)
     return SimpleEnclosedRegion(visible_layer_rect());
 
-  if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
+  if (blend_background_color_ && background_color().isOpaque())
     return SimpleEnclosedRegion(visible_layer_rect());
 
   return SimpleEnclosedRegion();
diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc
index 5ba92ea..dc36daa 100644
--- a/cc/layers/texture_layer_impl_unittest.cc
+++ b/cc/layers/texture_layer_impl_unittest.cc
@@ -36,15 +36,15 @@
 
   // Verify initial conditions.
   EXPECT_FALSE(layer->contents_opaque());
-  EXPECT_EQ(0u, layer->background_color());
+  EXPECT_EQ(SkColors::kTransparent, layer->background_color());
   EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
 
   // Opaque background.
-  layer->SetBackgroundColor(SK_ColorWHITE);
+  layer->SetBackgroundColor(SkColors::kWhite);
   EXPECT_EQ(layer_region.ToString(), layer->VisibleOpaqueRegion().ToString());
 
   // Transparent background.
-  layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
+  layer->SetBackgroundColor({1.0f, 1.0f, 1.0f, 0.5f});
   EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
 }
 
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc
index a47e0dc..57c8bf8 100644
--- a/cc/paint/oop_pixeltest.cc
+++ b/cc/paint/oop_pixeltest.cc
@@ -141,7 +141,7 @@
     oop_image_cache_ = std::make_unique<GpuImageDecodeCache>(
         raster_context_provider_.get(), true, kRGBA_8888_SkColorType,
         kWorkingSetSize, raster_max_texture_size,
-        PaintImage::kDefaultGeneratorClientId, nullptr);
+        PaintImage::GetNextGeneratorClientId(), nullptr);
   }
 
   class RasterOptions {
diff --git a/cc/paint/paint_image_unittest.cc b/cc/paint/paint_image_unittest.cc
index 45103e5..66289c6c 100644
--- a/cc/paint/paint_image_unittest.cc
+++ b/cc/paint/paint_image_unittest.cc
@@ -35,7 +35,7 @@
   SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
   std::vector<size_t> memory(info.computeMinByteSize());
   image.Decode(memory.data(), &info, nullptr, 1u,
-               PaintImage::kDefaultGeneratorClientId);
+               PaintImage::GetNextGeneratorClientId());
   ASSERT_EQ(generator->frames_decoded().size(), 1u);
   EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
   generator->reset_frames_decoded();
@@ -44,7 +44,7 @@
   info.makeColorType(kRGB_565_SkColorType);
   memory = std::vector<size_t>(info.computeMinByteSize());
   image.Decode(memory.data(), &info, nullptr, 1u,
-               PaintImage::kDefaultGeneratorClientId);
+               PaintImage::GetNextGeneratorClientId());
   ASSERT_EQ(generator->frames_decoded().size(), 1u);
   EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
   generator->reset_frames_decoded();
@@ -99,7 +99,7 @@
   ASSERT_EQ(yuva_pixmap_info, image_yuva_pixmap_info);
 
   image.DecodeYuv(pixmaps, 1u /* frame_index */,
-                  PaintImage::kDefaultGeneratorClientId);
+                  PaintImage::GetNextGeneratorClientId());
   ASSERT_EQ(yuv_generator->frames_decoded().size(), 1u);
   EXPECT_EQ(yuv_generator->frames_decoded().count(1u), 1u);
   yuv_generator->reset_frames_decoded();
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index a3ce347..759ddd5 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -44,7 +44,7 @@
       image_decode_cache_(
           kN32_SkColorType,
           LayerTreeSettings().decoded_image_working_set_budget_bytes,
-          PaintImage::kDefaultGeneratorClientId) {
+          PaintImage::GetNextGeneratorClientId()) {
   SetResources(resource_pool, &image_decode_cache_, GetGlobalTaskGraphRunner(),
                GetGlobalRasterBufferProvider(),
                /*use_gpu_rasterization=*/false, nullptr);
diff --git a/cc/test/test_layer_tree_host_base.cc b/cc/test/test_layer_tree_host_base.cc
index 26b5ef5..5d4d76ea 100644
--- a/cc/test/test_layer_tree_host_base.cc
+++ b/cc/test/test_layer_tree_host_base.cc
@@ -123,7 +123,7 @@
     pending_layer_->SetDrawsContent(true);
     // LCD-text tests require the layer to be initially opaque.
     pending_layer_->SetContentsOpaque(true);
-    pending_layer_->SetSafeOpaqueBackgroundColor(SK_ColorWHITE);
+    pending_layer_->SetSafeOpaqueBackgroundColor(SkColors::kWhite);
 
     pending_tree->SetElementIdsForTesting();
     SetupRootProperties(pending_root);
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index 889af5d..f9c24c2 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -991,6 +991,7 @@
       max_working_set_bytes_(max_working_set_bytes),
       max_working_set_items_(kMaxItemsInWorkingSet),
       dark_mode_filter_(dark_mode_filter) {
+  DCHECK_NE(generator_client_id_, PaintImage::kDefaultGeneratorClientId);
   // Note that to compute |allow_accelerated_jpeg_decodes_| and
   // |allow_accelerated_webp_decodes_|, the last thing we check is the feature
   // flag. That's because we want to ensure that we're in OOP-R mode and the
diff --git a/cc/tiles/gpu_image_decode_cache_perftest.cc b/cc/tiles/gpu_image_decode_cache_perftest.cc
index 6230a6b..0e8bba9 100644
--- a/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -55,7 +55,7 @@
     ASSERT_EQ(result, gpu::ContextResult::kSuccess);
     cache_ = std::make_unique<GpuImageDecodeCache>(
         context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType,
-        kCacheSize, MaxTextureSize(), PaintImage::kDefaultGeneratorClientId,
+        kCacheSize, MaxTextureSize(), PaintImage::GetNextGeneratorClientId(),
         nullptr);
   }
 
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index cef073a6..b72b54d5 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -429,7 +429,7 @@
     return std::make_unique<GpuImageDecodeCache>(
         context_provider_.get(), use_transfer_cache_, color_type_,
         memory_limit_bytes, max_texture_size_,
-        PaintImage::kDefaultGeneratorClientId, dark_mode_filter);
+        PaintImage::GetNextGeneratorClientId(), dark_mode_filter);
   }
 
   // Returns dimensions for an image that will not fit in GPU memory and hence
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc
index b709fab6..28b6a196 100644
--- a/cc/tiles/software_image_decode_cache.cc
+++ b/cc/tiles/software_image_decode_cache.cc
@@ -149,6 +149,7 @@
       color_type_(color_type),
       generator_client_id_(generator_client_id),
       max_items_in_cache_(kNormalMaxItemsInCacheForSoftware) {
+  DCHECK_NE(generator_client_id_, PaintImage::kDefaultGeneratorClientId);
   // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
   // Don't register a dump provider in these cases.
   if (base::ThreadTaskRunnerHandle::IsSet()) {
diff --git a/cc/tiles/software_image_decode_cache_unittest.cc b/cc/tiles/software_image_decode_cache_unittest.cc
index 52beb17..90abb8d 100644
--- a/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/cc/tiles/software_image_decode_cache_unittest.cc
@@ -29,7 +29,7 @@
   TestSoftwareImageDecodeCache()
       : SoftwareImageDecodeCache(kN32_SkColorType,
                                  kLockedMemoryLimitBytes,
-                                 PaintImage::kDefaultGeneratorClientId) {}
+                                 PaintImage::GetNextGeneratorClientId()) {}
 };
 
 SkM44 CreateMatrix(const SkSize& scale, bool is_decomposable) {
diff --git a/cc/tiles/software_image_decode_cache_unittest_combinations.cc b/cc/tiles/software_image_decode_cache_unittest_combinations.cc
index 4fc04c1..0a89147 100644
--- a/cc/tiles/software_image_decode_cache_unittest_combinations.cc
+++ b/cc/tiles/software_image_decode_cache_unittest_combinations.cc
@@ -83,7 +83,7 @@
   std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
     return std::make_unique<SoftwareImageDecodeCache>(
         kN32_SkColorType, kLockedMemoryLimitBytes,
-        PaintImage::kDefaultGeneratorClientId);
+        PaintImage::GetNextGeneratorClientId());
   }
 };
 
@@ -92,7 +92,7 @@
   std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
     return std::make_unique<SoftwareImageDecodeCache>(
         kARGB_4444_SkColorType, kLockedMemoryLimitBytes,
-        PaintImage::kDefaultGeneratorClientId);
+        PaintImage::GetNextGeneratorClientId());
   }
 };
 
@@ -101,7 +101,7 @@
   std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
     return std::make_unique<SoftwareImageDecodeCache>(
         kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
-        PaintImage::kDefaultGeneratorClientId);
+        PaintImage::GetNextGeneratorClientId());
   }
 };
 
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 8ce27018..7854fda 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -6248,7 +6248,7 @@
   auto* layer = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree());
   layer->SetBounds(gfx::Size(10, 10));
   layer->SetDrawsContent(true);
-  layer->SetBackgroundColor(SK_ColorRED);
+  layer->SetBackgroundColor(SkColors::kRed);
   CopyProperties(root, layer);
 
   UpdateDrawProperties(host_impl_->active_tree());
@@ -11049,7 +11049,7 @@
 
   layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10));
   // This will damage everything.
-  root->SetBackgroundColor(SK_ColorBLACK);
+  root->SetBackgroundColor(SkColors::kBlack);
   args = viz::CreateBeginFrameArgsForTesting(
       BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
       base::TimeTicks() + base::Milliseconds(1));
@@ -11256,13 +11256,13 @@
   auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(),
                                                    gfx::Size(10, 10));
   root->SetDrawsContent(true);
-  root->SetBackgroundColor(SK_ColorRED);
+  root->SetBackgroundColor(SkColors::kRed);
 
   // Child layer is in the bottom right corner.
   auto* child = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree());
   child->SetBounds(gfx::Size(1, 1));
   child->SetDrawsContent(true);
-  child->SetBackgroundColor(SK_ColorRED);
+  child->SetBackgroundColor(SkColors::kRed);
   CopyProperties(root, child);
   child->SetOffsetToTransformParent(gfx::Vector2dF(9, 9));
 
@@ -11527,7 +11527,7 @@
 
   LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>(
       host_impl_->active_tree(), gfx::Size(10, 10));
-  root->SetBackgroundColor(SK_ColorRED);
+  root->SetBackgroundColor(SkColors::kRed);
   UpdateDrawProperties(host_impl_->active_tree());
 
   // RequiresHighResToDraw is set when new output surface is used.
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index ab08e473..4ee8f4a 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -29,7 +29,6 @@
   "java/res/drawable-hdpi/btn_right.png",
   "java/res/drawable-hdpi/btn_tab_close_normal.png",
   "java/res/drawable-hdpi/btn_tabstrip_switch_normal.png",
-  "java/res/drawable-hdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-hdpi/cvc_icon.png",
   "java/res/drawable-hdpi/cvc_icon_amex.png",
   "java/res/drawable-hdpi/down_arrow.png",
@@ -101,7 +100,6 @@
   "java/res/drawable-mdpi/btn_right.png",
   "java/res/drawable-mdpi/btn_tab_close_normal.png",
   "java/res/drawable-mdpi/btn_tabstrip_switch_normal.png",
-  "java/res/drawable-mdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-mdpi/cvc_icon.png",
   "java/res/drawable-mdpi/cvc_icon_amex.png",
   "java/res/drawable-mdpi/down_arrow.png",
@@ -183,7 +181,6 @@
   "java/res/drawable-xhdpi/btn_right.png",
   "java/res/drawable-xhdpi/btn_tab_close_normal.png",
   "java/res/drawable-xhdpi/btn_tabstrip_switch_normal.png",
-  "java/res/drawable-xhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xhdpi/cvc_icon.png",
   "java/res/drawable-xhdpi/cvc_icon_amex.png",
   "java/res/drawable-xhdpi/down_arrow.png",
@@ -249,7 +246,6 @@
   "java/res/drawable-xxhdpi/btn_right.png",
   "java/res/drawable-xxhdpi/btn_tab_close_normal.png",
   "java/res/drawable-xxhdpi/btn_tabstrip_switch_normal.png",
-  "java/res/drawable-xxhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xxhdpi/cvc_icon.png",
   "java/res/drawable-xxhdpi/cvc_icon_amex.png",
   "java/res/drawable-xxhdpi/down_arrow.png",
@@ -315,7 +311,6 @@
   "java/res/drawable-xxxhdpi/btn_right.png",
   "java/res/drawable-xxxhdpi/btn_tab_close_normal.png",
   "java/res/drawable-xxxhdpi/btn_tabstrip_switch_normal.png",
-  "java/res/drawable-xxxhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xxxhdpi/cvc_icon.png",
   "java/res/drawable-xxxhdpi/cvc_icon_amex.png",
   "java/res/drawable-xxxhdpi/down_arrow.png",
@@ -500,7 +495,6 @@
   "java/res/layout/context_menu_header.xml",
   "java/res/layout/context_menu_row.xml",
   "java/res/layout/context_menu_share_row.xml",
-  "java/res/layout/contextual_search_bar_banner_text_view.xml",
   "java/res/layout/contextual_search_caption_view.xml",
   "java/res/layout/contextual_search_card_icon_view.xml",
   "java/res/layout/contextual_search_context_view.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index d2f0c76b..19bd5cc 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -301,7 +301,6 @@
   "java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelRepaddingTextView.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelTextViewInflater.java",
-  "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCaptionControl.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCardIconControl.java",
diff --git a/chrome/android/java/res/drawable-hdpi/contextual_search_promo_ripple.9.png b/chrome/android/java/res/drawable-hdpi/contextual_search_promo_ripple.9.png
deleted file mode 100644
index 1ee4b452..0000000
--- a/chrome/android/java/res/drawable-hdpi/contextual_search_promo_ripple.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/contextual_search_promo_ripple.9.png b/chrome/android/java/res/drawable-mdpi/contextual_search_promo_ripple.9.png
deleted file mode 100644
index 719e093c..0000000
--- a/chrome/android/java/res/drawable-mdpi/contextual_search_promo_ripple.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/contextual_search_promo_ripple.9.png b/chrome/android/java/res/drawable-xhdpi/contextual_search_promo_ripple.9.png
deleted file mode 100644
index 43e830e..0000000
--- a/chrome/android/java/res/drawable-xhdpi/contextual_search_promo_ripple.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/contextual_search_promo_ripple.9.png b/chrome/android/java/res/drawable-xxhdpi/contextual_search_promo_ripple.9.png
deleted file mode 100644
index 83dcfafb..0000000
--- a/chrome/android/java/res/drawable-xxhdpi/contextual_search_promo_ripple.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/contextual_search_promo_ripple.9.png b/chrome/android/java/res/drawable-xxxhdpi/contextual_search_promo_ripple.9.png
deleted file mode 100644
index dd0a735..0000000
--- a/chrome/android/java/res/drawable-xxxhdpi/contextual_search_promo_ripple.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml b/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml
deleted file mode 100644
index ce374ba..0000000
--- a/chrome/android/java/res/layout/contextual_search_bar_banner_text_view.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/contextual_search_bar_banner_text_view"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="horizontal"
-              android:paddingStart="@dimen/contextual_search_bar_banner_padding"
-              android:paddingEnd="@dimen/contextual_search_bar_banner_padding"
-              android:visibility="invisible">
-
-    <TextView
-        android:id="@+id/contextual_search_iph_tap_text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.TextMedium.Primary.Baseline.Light"
-        android:text="@string/contextual_search_iph_tap"
-        />
-</LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index a9ffbc4..7059148 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -40,7 +40,6 @@
     <dimen name="overlay_panel_caption_spacing">1.5dp</dimen>
 
     <!-- Contextual Search dimensions -->
-    <dimen name="contextual_search_bar_banner_padding">12dp</dimen>
     <dimen name="contextual_search_bar_image_size">36dp</dimen>
     <dimen name="contextual_search_text_layer_min_height">
         @dimen/overlay_panel_text_layer_min_height
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java
deleted file mode 100644
index 77cb77f..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java
+++ /dev/null
@@ -1,297 +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.
-
-package org.chromium.chrome.browser.compositor.bottombar.contextualsearch;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
-import android.view.ViewGroup;
-
-import org.chromium.base.MathUtils;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
-import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelAnimation;
-import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelInflater;
-import org.chromium.chrome.browser.layouts.animation.CompositorAnimator;
-import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
-
-/**
- * Controls the Search Bar Banner, which presents a banner above the Bar.
- * This can be used for promotional features.
- * TODO(donnd): consider removal since this is currently unused.
- */
-public class ContextualSearchBarBannerControl extends OverlayPanelInflater {
-    /**
-     * The initial width of the ripple for the appearance animation, in dps.
-     */
-    private static final float RIPPLE_MINIMUM_WIDTH_DP = 56.f;
-
-    /**
-     * Whether the Bar Banner is visible.
-     */
-    private boolean mIsVisible;
-
-    /**
-     * Whether the Bar Banner is in the process of hiding.
-     */
-    private boolean mIsHiding;
-
-    /**
-     * The height of the Bar Banner, in pixels.
-     */
-    private float mHeightPx;
-
-    /**
-     * The width of the Ripple resource in pixels.
-     */
-    private float mRippleWidthPx;
-
-    /**
-     * The opacity of the Ripple resource.
-     */
-    private float mRippleOpacity;
-
-    /**
-     * The opacity of the Text View dynamic resource.
-     */
-    private float mTextOpacity;
-
-    /**
-     * The precomputed padding of the Bar Banner, in pixels.
-     */
-    private final float mPaddingPx;
-
-    /**
-     * The padded height of the Bar Banner in pixels. Set to zero initially, calculated on the first
-     * call.
-     */
-    private float mPaddedHeightPx;
-
-    /**
-     * The precomputed minimum width of the Ripple resource in pixels.
-     */
-    private final float mRippleMinimumWidthPx;
-
-    /**
-     * The precomputed maximum width of the Ripple resource in pixels.
-     */
-    private float mRippleMaximumWidthPx;
-
-    /**
-     * @param panel             The panel.
-     * @param context           The Android Context used to inflate the View.
-     * @param container         The container View used to inflate the View.
-     * @param resourceLoader    The resource loader that will handle the snapshot capturing.
-     */
-    public ContextualSearchBarBannerControl(OverlayPanel panel, Context context,
-            ViewGroup container, DynamicResourceLoader resourceLoader) {
-        super(panel, R.layout.contextual_search_bar_banner_text_view,
-                R.id.contextual_search_bar_banner_text_view, context, container, resourceLoader);
-
-        final float dpToPx = context.getResources().getDisplayMetrics().density;
-
-        mPaddingPx = context.getResources().getDimensionPixelOffset(
-                R.dimen.contextual_search_bar_banner_padding);
-
-        mRippleMinimumWidthPx = RIPPLE_MINIMUM_WIDTH_DP * dpToPx;
-        mRippleMaximumWidthPx = panel.getMaximumWidthPx();
-    }
-
-    /**
-     * Shows the Bar Banner. This includes inflating the View and setting it to its initial state.
-     * This also means a new cc::Layer will be created and added to the tree.
-     */
-    void show() {
-        if (mIsVisible) return;
-
-        mIsVisible = true;
-        mHeightPx = Math.round(getPaddedHeightPx());
-
-        invalidate();
-    }
-
-    /**
-     * Hides the Bar Banner, returning the Control to its initial uninitialized state. In this
-     * state, now View will be created and no Layer added to the tree (or removed if present).
-     */
-    void hide() {
-        if (!mIsVisible) return;
-
-        if (mHeightPx == 0.f) {
-            mIsVisible = false;
-        } else {
-            animateDisappearance();
-        }
-    }
-
-    /**
-     * @return The height of the Bar Banner when the Panel is the peeked state.
-     */
-    float getHeightPeekingPx() {
-        return (!isVisible() || mIsHiding) ? 0.f : getPaddedHeightPx();
-    }
-
-    /** Calculates the padded height of the bar banner if it has not been calculated before.
-     * @return The padded height of the Bar Banner.
-     */
-    private float getPaddedHeightPx() {
-        if (mPaddedHeightPx == 0.f) {
-            // Calculate the padded height based on the measured height of the TextView.
-            inflate();
-            layout();
-            mPaddedHeightPx = getMeasuredHeight() + (2 * mPaddingPx);
-        }
-        return mPaddedHeightPx;
-    }
-
-    // ============================================================================================
-    // Custom Behaviors
-    // ============================================================================================
-
-    void onResized(ContextualSearchPanel panel) {
-        mRippleMaximumWidthPx = panel.getMaximumWidthPx();
-
-        // In the rare condition that size is changed mid-animation, e.g. the device orientation is
-        // changed, mRippleWidthPx will be updated by the CompositorAnimator and will grow to the
-        // new mRippleMaximumWidthPx by the end of animation.
-        mRippleWidthPx = mRippleMaximumWidthPx;
-    }
-
-    // ============================================================================================
-    // Public API
-    // ============================================================================================
-
-    /**
-     * @return Whether the Bar Banner is visible.
-     */
-    public boolean isVisible() {
-        return mIsVisible;
-    }
-
-    /**
-     * @return The Bar Banner height in pixels.
-     */
-    public float getHeightPx() {
-        return mHeightPx;
-    }
-
-    /**
-     * @return The Bar Banner padding in pixels.
-     */
-    public float getPaddingPx() {
-        return mPaddingPx;
-    }
-
-    /**
-     * @return The width of the Ripple resource in pixels.
-     */
-    public float getRippleWidthPx() {
-        return mRippleWidthPx;
-    }
-
-    /**
-     * @return The opacity of the Ripple resource.
-     */
-    public float getRippleOpacity() {
-        return mRippleOpacity;
-    }
-
-    /**
-     * @return The opacity of the Text View dynamic resource.
-     */
-    public float getTextOpacity() {
-        return mTextOpacity;
-    }
-
-    // ============================================================================================
-    // Panel Animation
-    // ============================================================================================
-
-    /**
-     * Interpolates the UI from states Closed to Peeked.
-     *
-     * @param percentage The completion percentage.
-     */
-    public void onUpdateFromCloseToPeek(float percentage) {
-        if (!isVisible() || mIsHiding) return;
-
-        mHeightPx = Math.round(getPaddedHeightPx());
-    }
-
-    /**
-     * Interpolates the UI from states Peeked to Expanded.
-     *
-     * @param percentage The completion percentage.
-     */
-    public void onUpdateFromPeekToExpand(float percentage) {
-        if (!isVisible() || mIsHiding) return;
-
-        mHeightPx = Math.round(MathUtils.interpolate(getPaddedHeightPx(), 0.f, percentage));
-        mTextOpacity = MathUtils.interpolate(1.f, 0.f, percentage);
-    }
-
-    /**
-     * Interpolates the UI from states Expanded to Maximized.
-     *
-     * @param percentage The completion percentage.
-     */
-    public void onUpdateFromExpandToMaximize(float percentage) {
-        if (!isVisible() || mIsHiding) return;
-
-        mHeightPx = 0.f;
-        mTextOpacity = 0.f;
-    }
-
-    // ============================================================================================
-    // Bar Banner Appearance Animation
-    // ============================================================================================
-
-    /**
-     * Animates the Bar Banner appearance.
-     */
-    public void animateAppearance() {
-        CompositorAnimator rippleWidth = CompositorAnimator.ofFloat(
-                mOverlayPanel.getAnimationHandler(), mRippleMinimumWidthPx, mRippleMaximumWidthPx,
-                OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS,
-                animator -> { mRippleWidthPx = animator.getAnimatedValue(); });
-        CompositorAnimator rippleOpacity =
-                CompositorAnimator.ofFloat(mOverlayPanel.getAnimationHandler(), 0.f, 1.f,
-                        OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS,
-                        animator -> { mRippleOpacity = animator.getAnimatedValue(); });
-        CompositorAnimator textOpacity =
-                CompositorAnimator.ofFloat(mOverlayPanel.getAnimationHandler(), 0.f, 1.f,
-                        OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS / 2,
-                        animator -> { mTextOpacity = animator.getAnimatedValue(); });
-        textOpacity.setStartDelay(OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS / 2);
-
-        rippleWidth.start();
-        rippleOpacity.start();
-        textOpacity.start();
-    }
-
-    /**
-     * Animates the Bar Banner disappearance.
-     */
-    private void animateDisappearance() {
-        mIsHiding = true;
-        CompositorAnimator disappearance =
-                CompositorAnimator.ofFloat(mOverlayPanel.getAnimationHandler(), getPaddedHeightPx(),
-                        0.f, OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, null);
-        disappearance.addUpdateListener(animator -> {
-            if (isVisible()) {
-                mHeightPx = animator.getAnimatedValue();
-            }
-        });
-        disappearance.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mHeightPx = 0.f;
-                mIsHiding = false;
-                hide();
-            }
-        });
-        disappearance.start();
-    }
-}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index dc05b23..3682f28 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -198,9 +198,9 @@
     public SceneOverlayLayer getUpdatedSceneOverlayTree(
             RectF viewport, RectF visibleViewport, ResourceManager resourceManager, float yOffset) {
         super.getUpdatedSceneOverlayTree(viewport, visibleViewport, resourceManager, yOffset);
-        mSceneLayer.update(resourceManager, this, getSearchBarControl(), getBarBannerControl(),
-                getPromoControl(), getRelatedSearchesInBarControl(),
-                getRelatedSearchesInContentControl(), getImageControl());
+        mSceneLayer.update(resourceManager, this, getSearchBarControl(), getPromoControl(),
+                getRelatedSearchesInBarControl(), getRelatedSearchesInContentControl(),
+                getImageControl());
 
         return mSceneLayer;
     }
@@ -246,14 +246,6 @@
         mPanelMetrics.onPanelStateChanged(
                 fromState, toState, reason, Profile.getLastUsedRegularProfile());
 
-        if (toState == PanelState.PEEKED
-                && (fromState == PanelState.CLOSED || fromState == PanelState.UNDEFINED)) {
-            // If the Bar Banner is visible, it should animate when the SearchBar peeks.
-            if (getBarBannerControl().isVisible()) {
-                getBarBannerControl().animateAppearance();
-            }
-        }
-
         if (toState == PanelState.CLOSED || toState == PanelState.UNDEFINED) {
             mManagementDelegate.onPanelFinishedShowing();
         }
@@ -386,7 +378,6 @@
         destroyPromoControl();
         destroyInBarRelatedSearchesControl();
         destroyInContentRelatedSearchesControl();
-        destroyBarBannerControl();
         destroySearchBarControl();
     }
 
@@ -443,12 +434,12 @@
 
     @Override
     public float getBarContainerHeight() {
-        return getBarHeight() + getBarBannerControl().getHeightPx();
+        return getBarHeight();
     }
 
     @Override
     protected float getPeekedHeight() {
-        return getBarHeight() + getBarBannerControl().getHeightPeekingPx() * mPxToDp;
+        return getBarHeight();
     }
 
     @Override
@@ -536,28 +527,6 @@
     }
 
     /**
-     * Shows the Bar Banner.
-     */
-    public void showBarBanner() {
-        getBarBannerControl().show();
-    }
-
-    /**
-     * Hides the Bar Banner.
-     */
-    public void hideBarBanner() {
-        getBarBannerControl().hide();
-    }
-
-    /**
-     * @return Whether the Bar Banner is visible.
-     */
-    @VisibleForTesting
-    public boolean isBarBannerVisible() {
-        return getBarBannerControl().isVisible();
-    }
-
-    /**
      * Called after the panel has navigated to prefetched Search Results.
      * If the user has the panel open then they will see the prefetched result starting to load.
      * Currently this just logs the time between the start of the search until the results start to
@@ -855,7 +824,6 @@
         getPromoControl().onUpdateFromCloseToPeek(percentage);
         getRelatedSearchesInBarControl().onUpdateFromCloseToPeek(percentage);
         getRelatedSearchesInContentControl().onUpdateFromCloseToPeek(percentage);
-        getBarBannerControl().onUpdateFromCloseToPeek(percentage);
         getSearchBarControl().onUpdateFromCloseToPeek(percentage);
         mDidStartCollapsing = false;
     }
@@ -874,7 +842,6 @@
         getPromoControl().onUpdateFromPeekToExpand(percentage);
         getRelatedSearchesInBarControl().onUpdateFromPeekToExpand(percentage);
         getRelatedSearchesInContentControl().onUpdateFromPeekToExpand(percentage);
-        getBarBannerControl().onUpdateFromPeekToExpand(percentage);
         getSearchBarControl().onUpdateFromPeekToExpand(percentage);
     }
 
@@ -885,7 +852,6 @@
         getPromoControl().onUpdateFromExpandToMaximize(percentage);
         getRelatedSearchesInBarControl().onUpdateFromExpandToMaximize(percentage);
         getRelatedSearchesInContentControl().onUpdateFromExpandToMaximize(percentage);
-        getBarBannerControl().onUpdateFromExpandToMaximize(percentage);
         getSearchBarControl().onUpdateFromExpandToMaximize(percentage);
     }
 
@@ -900,9 +866,6 @@
         if (getRelatedSearchesInContentControl().isVisible()) {
             getRelatedSearchesInContentControl().invalidate(true);
         }
-        if (getBarBannerControl().isVisible()) {
-            getBarBannerControl().onResized(this);
-        }
 
         // NOTE(pedrosimonetti): We cannot tell where the selection will be after the
         // orientation change, so we are setting the selection position to zero, which
@@ -1026,33 +989,6 @@
     }
 
     // ============================================================================================
-    // Bar Banner
-    // ============================================================================================
-
-    private ContextualSearchBarBannerControl mBarBannerControl;
-
-    /**
-     * Creates the ContextualSearchBarBannerControl, if needed.
-     */
-    private ContextualSearchBarBannerControl getBarBannerControl() {
-        if (mBarBannerControl == null) {
-            mBarBannerControl = new ContextualSearchBarBannerControl(
-                    this, mContext, mContainerView, mResourceLoader);
-        }
-        return mBarBannerControl;
-    }
-
-    /**
-     * Destroys the ContextualSearchBarBannerControl.
-     */
-    private void destroyBarBannerControl() {
-        if (mBarBannerControl != null) {
-            mBarBannerControl.destroy();
-            mBarBannerControl = null;
-        }
-    }
-
-    // ============================================================================================
     // Promo
     // ============================================================================================
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
index 20572d4..95c5d35 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
@@ -10,7 +10,6 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchBarBannerControl;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchBarControl;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchImageControl;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
@@ -47,7 +46,6 @@
      * @param resourceManager Manager to get view and image resources.
      * @param panel The OverlayPanel to render.
      * @param searchBarControl The Search Bar control.
-     * @param barBannerControl An optional banner that shows above the Bar as a promo.
      * @param promoControl The privacy Opt-in promo that appears below the Bar.
      * @param relatedSearchesInBarControl A control that displays Related Searches suggestions
      *        in the Bar to facilitate one-click searching.
@@ -56,9 +54,7 @@
      * @param imageControl The object controlling the image displayed in the Bar.
      */
     public void update(ResourceManager resourceManager, ContextualSearchPanel panel,
-            ContextualSearchBarControl searchBarControl,
-            ContextualSearchBarBannerControl barBannerControl,
-            ContextualSearchPromoControl promoControl,
+            ContextualSearchBarControl searchBarControl, ContextualSearchPromoControl promoControl,
             RelatedSearchesControl relatedSearchesInBarControl,
             RelatedSearchesControl relatedSearchesInContentControl,
             ContextualSearchImageControl imageControl) {
@@ -101,15 +97,6 @@
                 panel.getInBarRelatedSearchesAnimatedHeightDps() * mDpToPx
                 - relatedSearchesInBarRedundantPadding;
 
-        // Banner etc.
-        int searchBarBannerTextViewId = barBannerControl.getViewId();
-        boolean searchBarBannerVisible = barBannerControl.isVisible();
-        float searchBarBannerHeightPx = barBannerControl.getHeightPx();
-        float searchBarBannerPaddingPx = barBannerControl.getPaddingPx();
-        float searchBarBannerRippleWidthPx = barBannerControl.getRippleWidthPx();
-        float searchBarBannerRippleOpacity = barBannerControl.getRippleOpacity();
-        float searchBarBannerTextOpacity = barBannerControl.getTextOpacity();
-
         float customImageVisibilityPercentage = imageControl.getCustomImageVisibilityPercentage();
         int barImageSize = imageControl.getBarImageSize();
 
@@ -170,8 +157,7 @@
                 R.drawable.modern_toolbar_shadow, R.drawable.ic_logo_googleg_24dp,
                 quickActionIconResId, dragHandlebarId, openNewTabIconId, closeIconResourceId,
                 R.drawable.progress_bar_background, progressBarBackgroundColor,
-                R.drawable.progress_bar_foreground, progressBarColor, searchPromoViewId,
-                R.drawable.contextual_search_promo_ripple, searchBarBannerTextViewId, mDpToPx,
+                R.drawable.progress_bar_foreground, progressBarColor, searchPromoViewId, mDpToPx,
                 panel.getFullscreenWidth() * mDpToPx, panel.getTabHeight() * mDpToPx,
                 panel.getBasePageBrightness(), panel.getBasePageY() * mDpToPx, panelWebContents,
                 searchPromoVisible, searchPromoHeightPx, searchPromoOpacity,
@@ -181,13 +167,10 @@
                 relatedSearchesInContentHeightPx, relatedSearchesInBarViewId,
                 relatedSearchesInBarVisible, relatedSearchesInBarHeight,
                 relatedSearchesInBarRedundantPadding,
-                // Banner etc.
-                searchBarBannerVisible, searchBarBannerHeightPx, searchBarBannerPaddingPx,
-                searchBarBannerRippleWidthPx, searchBarBannerRippleOpacity,
-                searchBarBannerTextOpacity, searchPanelX * mDpToPx, searchPanelY * mDpToPx,
-                searchPanelWidth * mDpToPx, searchPanelHeight * mDpToPx,
-                searchBarMarginSide * mDpToPx, searchBarMarginTop * mDpToPx,
-                searchBarHeight * mDpToPx, searchContextOpacity,
+                // Panel position etc.
+                searchPanelX * mDpToPx, searchPanelY * mDpToPx, searchPanelWidth * mDpToPx,
+                searchPanelHeight * mDpToPx, searchBarMarginSide * mDpToPx,
+                searchBarMarginTop * mDpToPx, searchBarHeight * mDpToPx, searchContextOpacity,
                 searchBarControl.getTextLayerMinHeight(), searchTermOpacity,
                 searchBarControl.getSearchTermCaptionSpacing(), searchCaptionAnimationPercentage,
                 searchCaptionVisible, searchBarBorderVisible, searchBarBorderHeight * mDpToPx,
@@ -252,8 +235,7 @@
                 int dragHandlebarResourceId, int openTabIconResourceId, int closeIconResourceId,
                 int progressBarBackgroundResourceId, int progressBarBackgroundColor,
                 int progressBarResourceId, int progressBarColor, int searchPromoResourceId,
-                int barBannerRippleResourceId, int barBannerTextResourceId, float dpToPx,
-                float layoutWidth, float layoutHeight, float basePageBrightness,
+                float dpToPx, float layoutWidth, float layoutHeight, float basePageBrightness,
                 float basePageYOffset, WebContents webContents, boolean searchPromoVisible,
                 float searchPromoHeight, float searchPromoOpacity, int searchPromoBackgroundColor,
                 // Related Searches
@@ -261,10 +243,7 @@
                 float relatedSearchesInContentHeight, int relatedSearchesInBarResourceId,
                 boolean relatedSearchesInBarVisible, float relatedSearchesInBarHeight,
                 float relatedSearchesInBarRedundantPadding,
-                // Banner etc
-                boolean searchBarBannerVisible, float searchBarBannerHeight,
-                float searchBarBannerPaddingPx, float searchBarBannerRippleWidth,
-                float searchBarBannerRippleOpacity, float searchBarBannerTextOpacity,
+                // Panel position etc
                 float searchPanelX, float searchPanelY, float searchPanelWidth,
                 float searchPanelHeight, float searchBarMarginSide, float searchBarMarginTop,
                 float searchBarHeight, float searchContextOpacity, float searchTextLayerMinHeight,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
index bae0943e..d9835ad 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
@@ -320,31 +320,43 @@
 
     //--------------------------------------------------------------------------------------------
     // Feature maps that we use for parameterized tests.
+    // NOTE: We want to test all Features under development both on and off, regardless of whether
+    // they are enabled in fieldtrial_testing_config.json, to catch regressions during rollout.
     //--------------------------------------------------------------------------------------------
 
-    /** This represents the current fully-launched configuration, with no other Features. */
-    protected static final ImmutableMap<String, Boolean> ENABLE_NONE = ImmutableMap.of();
-
-    /** This is the helper-test Feature. */
-    private static final ImmutableMap<String, Boolean> ENABLE_FORCE_CAPTION =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true);
+    /**
+     * This represents the current fully-launched configuration, with no other Features.
+     */
+    protected static final ImmutableMap<String, Boolean> ENABLE_NONE = ImmutableMap.of(
+            // All false
+            ChromeFeatureList.RELATED_SEARCHES, false, ChromeFeatureList.RELATED_SEARCHES_IN_BAR,
+            false, ChromeFeatureList.RELATED_SEARCHES_UI, false,
+            ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, false,
+            ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, false);
 
     /** This is the Related Searches Feature in the MVP configuration. */
     private static final ImmutableMap<String, Boolean> ENABLE_RELATED_SEARCHES = ImmutableMap.of(
+            // Related Searches needs these 3:
             ChromeFeatureList.RELATED_SEARCHES, true, ChromeFeatureList.RELATED_SEARCHES_IN_BAR,
-            true, ChromeFeatureList.RELATED_SEARCHES_UI, true);
+            true, ChromeFeatureList.RELATED_SEARCHES_UI, true,
+            ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, false,
+            ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, false);
+
+    /** This is the helper-test Feature. */
+    private static final ImmutableMap<String, Boolean> ENABLE_FORCE_CAPTION = ImmutableMap.of(
+            ChromeFeatureList.RELATED_SEARCHES, false, ChromeFeatureList.RELATED_SEARCHES_IN_BAR,
+            false, ChromeFeatureList.RELATED_SEARCHES_UI, false,
+            // Just this one enabled:
+            ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true,
+            ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, false);
 
     /** This is the contextual triggers feature set that alters tap to show selection handles. */
-    private static final ImmutableMap<String, Boolean> ENABLE_CONTEXTUAL_TRIGGERS =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, true);
-
-    /**
-     * This is the contextual triggers feature set that alters tap to show handles and shows the
-     * context menu.
-     */
-    private static final ImmutableMap<String, Boolean> ENABLE_CONTEXTUAL_TRIGGERS_MENU =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, true,
-                    ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_MENU, true);
+    private static final ImmutableMap<String, Boolean> ENABLE_CONTEXTUAL_TRIGGERS = ImmutableMap.of(
+            ChromeFeatureList.RELATED_SEARCHES, false, ChromeFeatureList.RELATED_SEARCHES_IN_BAR,
+            false, ChromeFeatureList.RELATED_SEARCHES_UI, false,
+            ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, false,
+            // Just this one enabled:
+            ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, true);
 
     //--------------------------------------------------------------------------------------------
     // Feature maps that we use for individual tests.
@@ -376,7 +388,7 @@
 
     @IntDef({EnabledFeature.NONE, EnabledFeature.TRANSLATIONS, EnabledFeature.PRIVACY_NEUTRAL,
             EnabledFeature.PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES,
-            EnabledFeature.CONTEXTUAL_TRIGGERS, EnabledFeature.CONTEXTUAL_TRIGGERS_MENU})
+            EnabledFeature.CONTEXTUAL_TRIGGERS})
     @Retention(RetentionPolicy.SOURCE)
     @interface EnabledFeature {
         int NONE = 0;
@@ -384,7 +396,6 @@
         int PRIVACY_NEUTRAL = 2;
         int PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES = 3;
         int CONTEXTUAL_TRIGGERS = 4;
-        int CONTEXTUAL_TRIGGERS_MENU = 5;
     }
 
     // Tracks whether a long-press triggering experiment is active.
@@ -468,9 +479,6 @@
             case EnabledFeature.CONTEXTUAL_TRIGGERS:
                 whichFeature = ENABLE_CONTEXTUAL_TRIGGERS;
                 break;
-            case EnabledFeature.CONTEXTUAL_TRIGGERS_MENU:
-                whichFeature = ENABLE_CONTEXTUAL_TRIGGERS_MENU;
-                break;
         }
         Assert.assertNotNull(
                 "Did you change test Features without setting the correct Map?", whichFeature);
diff --git a/chrome/browser/accessibility/accessibility_labels_service.cc b/chrome/browser/accessibility/accessibility_labels_service.cc
index 8d7afc6..bab03a4 100644
--- a/chrome/browser/accessibility/accessibility_labels_service.cc
+++ b/chrome/browser/accessibility/accessibility_labels_service.cc
@@ -233,14 +233,15 @@
   // We only need to fire this event for the active page.
   ui::AXActionData action_data;
   action_data.action = ax::mojom::Action::kAnnotatePageImages;
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      [](const ui::AXActionData& action_data,
-         content::RenderFrameHost* render_frame_host) {
-        if (render_frame_host->IsRenderFrameLive()) {
-          render_frame_host->AccessibilityPerformAction(action_data);
-        }
-      },
-      action_data));
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(
+          [](const ui::AXActionData& action_data,
+             content::RenderFrameHost* render_frame_host) {
+            if (render_frame_host->IsRenderFrameLive()) {
+              render_frame_host->AccessibilityPerformAction(action_data);
+            }
+          },
+          action_data));
 #endif
 }
 
@@ -356,13 +357,14 @@
   // We only need to fire this event for the active page.
   ui::AXActionData action_data;
   action_data.action = ax::mojom::Action::kAnnotatePageImages;
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      [](const ui::AXActionData& action_data,
-         content::RenderFrameHost* render_frame_host) {
-        if (render_frame_host->IsRenderFrameLive()) {
-          render_frame_host->AccessibilityPerformAction(action_data);
-        }
-      },
-      action_data));
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(
+          [](const ui::AXActionData& action_data,
+             content::RenderFrameHost* render_frame_host) {
+            if (render_frame_host->IsRenderFrameLive()) {
+              render_frame_host->AccessibilityPerformAction(action_data);
+            }
+          },
+          action_data));
 }
 #endif
diff --git a/chrome/browser/accessibility/ax_screen_ai_annotator.cc b/chrome/browser/accessibility/ax_screen_ai_annotator.cc
index 518ccdde..56d93da 100644
--- a/chrome/browser/accessibility/ax_screen_ai_annotator.cc
+++ b/chrome/browser/accessibility/ax_screen_ai_annotator.cc
@@ -39,7 +39,7 @@
       native_view, gfx::Rect(web_contents->GetSize()),
       base::BindOnce(&AXScreenAIAnnotator::OnScreenshotReceived,
                      weak_ptr_factory_.GetWeakPtr(),
-                     web_contents->GetMainFrame()->GetAXTreeID()));
+                     web_contents->GetPrimaryMainFrame()->GetAXTreeID()));
 }
 
 void AXScreenAIAnnotator::OnScreenshotReceived(const ui::AXTreeID& ax_tree_id,
diff --git a/chrome/browser/accessibility/live_caption_speech_recognition_host_browsertest.cc b/chrome/browser/accessibility/live_caption_speech_recognition_host_browsertest.cc
index aefe276..acd07484 100644
--- a/chrome/browser/accessibility/live_caption_speech_recognition_host_browsertest.cc
+++ b/chrome/browser/accessibility/live_caption_speech_recognition_host_browsertest.cc
@@ -137,8 +137,10 @@
 // Disabled due to flaky crashes; https://crbug.com/1216304.
 IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest,
                        DISABLED_DestroysWithoutCrashing) {
-  content::RenderFrameHost* frame_host =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* frame_host = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   CreateLiveCaptionSpeechRecognitionHost(frame_host);
 
   SetLiveCaptionEnabled(true);
@@ -153,8 +155,10 @@
       ui_test_utils::NavigateToURL(browser(), GURL("http://www.google.com")));
   content::WaitForLoadStop(
       browser()->tab_strip_model()->GetActiveWebContents());
-  content::RenderFrameHost* new_frame_host =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* new_frame_host = browser()
+                                                 ->tab_strip_model()
+                                                 ->GetActiveWebContents()
+                                                 ->GetPrimaryMainFrame();
   // After navigating to a new URL, the main frame should be different from the
   // former frame host.
   CreateLiveCaptionSpeechRecognitionHost(new_frame_host);
@@ -169,8 +173,10 @@
 
 IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest,
                        OnSpeechRecognitionRecognitionEvent) {
-  content::RenderFrameHost* frame_host =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* frame_host = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   CreateLiveCaptionSpeechRecognitionHost(frame_host);
 
   SetLiveCaptionEnabled(true);
@@ -190,8 +196,10 @@
 
 IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest,
                        OnLanguageIdentificationEvent) {
-  content::RenderFrameHost* frame_host =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* frame_host = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   CreateLiveCaptionSpeechRecognitionHost(frame_host);
 
   SetLiveCaptionEnabled(true);
@@ -201,8 +209,10 @@
 
 IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest,
                        OnSpeechRecognitionError) {
-  content::RenderFrameHost* frame_host =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* frame_host = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   CreateLiveCaptionSpeechRecognitionHost(frame_host);
 
   SetLiveCaptionEnabled(true);
@@ -214,7 +224,7 @@
                        MediaEffectivelyFullscreenChanged) {
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame_host = web_contents->GetPrimaryMainFrame();
   CreateLiveCaptionSpeechRecognitionHost(frame_host);
   EXPECT_TRUE(content::NavigateToURL(
       web_contents, embedded_test_server()->GetURL("/media/fullscreen.html")));
diff --git a/chrome/browser/android/compositor/layer/contextual_search_layer.cc b/chrome/browser/android/compositor/layer/contextual_search_layer.cc
index b1c2d84..1ca2798 100644
--- a/chrome/browser/android/compositor/layer/contextual_search_layer.cc
+++ b/chrome/browser/android/compositor/layer/contextual_search_layer.cc
@@ -18,8 +18,6 @@
 namespace {
 
 const SkColor kSearchBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
-const SkColor kSearchBarBackgroundColor = SkColorSetRGB(0xff, 0xff, 0xff);
-const SkColor kBarBannerRippleBackgroundColor = SkColorSetRGB(0x42, 0x85, 0xF4);
 const SkColor kTouchHighlightColor = SkColorSetARGB(0x33, 0x99, 0x99, 0x99);
 
 }  // namespace
@@ -49,8 +47,6 @@
     int progress_bar_resource_id,
     int progress_bar_tint,
     int search_promo_resource_id,
-    int bar_banner_ripple_resource_id,
-    int bar_banner_text_resource_id,
     float dp_to_px,
     const scoped_refptr<cc::Layer>& content_layer,
     bool search_promo_visible,
@@ -65,13 +61,7 @@
     bool related_searches_in_bar_visible,
     float related_searches_in_bar_height,
     float related_searches_in_bar_redundant_padding,
-    // Banner etc
-    bool search_bar_banner_visible,
-    float search_bar_banner_height,
-    float search_bar_banner_padding,
-    float search_bar_banner_ripple_width,
-    float search_bar_banner_ripple_opacity,
-    float search_bar_banner_text_opacity,
+    // Position etc
     float search_panel_x,
     float search_panel_y,
     float search_panel_width,
@@ -106,7 +96,7 @@
   // Round values to avoid pixel gap between layers.
   search_bar_height = floor(search_bar_height);
 
-  float search_bar_top = search_bar_banner_height;
+  float search_bar_top = 0.f;
   float search_bar_bottom = search_bar_top + search_bar_height;
   bool should_render_progress_bar =
       progress_bar_visible && progress_bar_opacity > 0.f;
@@ -137,102 +127,10 @@
   // -----------------------------------------------------------------
   // Content setup, to center in space below drag handle.
   // -----------------------------------------------------------------
-  bool is_rtl = l10n_util::IsLayoutRtl();
   int content_height = search_bar_height - search_bar_margin_top -
                        related_searches_in_bar_height;
   int content_top = search_bar_top + search_bar_margin_top;
 
-  // -----------------------------------------------------------------
-  // Bar Banner -- obsolete.  TODO(donnd): remove.
-  // -----------------------------------------------------------------
-  if (search_bar_banner_visible) {
-    // Grabs the Bar Banner resource.
-    ui::Resource* bar_banner_text_resource = resource_manager_->GetResource(
-        ui::ANDROID_RESOURCE_TYPE_DYNAMIC, bar_banner_text_resource_id);
-
-    ui::NinePatchResource* bar_banner_ripple_resource =
-        ui::NinePatchResource::From(resource_manager_->GetResource(
-            ui::ANDROID_RESOURCE_TYPE_STATIC, bar_banner_ripple_resource_id));
-
-    // -----------------------------------------------------------------
-    // Bar Banner Container
-    // -----------------------------------------------------------------
-    if (bar_banner_container_->parent() != layer_) {
-      layer_->AddChild(bar_banner_container_);
-    }
-
-    gfx::Size bar_banner_size(search_panel_width, search_bar_banner_height);
-    bar_banner_container_->SetBounds(bar_banner_size);
-    bar_banner_container_->SetPosition(gfx::PointF(0.f, 0.f));
-    bar_banner_container_->SetMasksToBounds(true);
-
-    // Apply a blend based on the ripple opacity. The resulting color will
-    // be an interpolation between the background color of the Search Bar and
-    // a lighter shade of the background color of the Ripple.
-    // TODO(crbug/1308932): Remove toSkColor and FromColor and make all
-    // SkColor4f.
-    bar_banner_container_->SetBackgroundColor(
-        SkColor4f::FromColor(color_utils::AlphaBlend(
-            kBarBannerRippleBackgroundColor, search_bar_background_color,
-            0.25f * search_bar_banner_ripple_opacity)));
-
-    // -----------------------------------------------------------------
-    // Bar Banner Ripple
-    // -----------------------------------------------------------------
-    gfx::Size bar_banner_ripple_size(search_bar_banner_ripple_width,
-                                     search_bar_banner_height);
-    gfx::Rect bar_banner_ripple_border(
-        bar_banner_ripple_resource->Border(bar_banner_ripple_size));
-
-    // Add padding so the ripple will occupy the whole width at 100%.
-    bar_banner_ripple_size.set_width(bar_banner_ripple_size.width() +
-                                     bar_banner_ripple_border.width());
-
-    float ripple_rotation = 0.f;
-    float ripple_left = 0.f;
-    if (is_rtl) {
-      // Rotate the ripple 180 degrees to make it point to the left side.
-      ripple_rotation = 180.f;
-      ripple_left = search_panel_width - bar_banner_ripple_size.width();
-    }
-
-    bar_banner_ripple_->SetUIResourceId(
-        bar_banner_ripple_resource->ui_resource()->id());
-    bar_banner_ripple_->SetBorder(bar_banner_ripple_border);
-    bar_banner_ripple_->SetAperture(bar_banner_ripple_resource->aperture());
-    bar_banner_ripple_->SetBounds(bar_banner_ripple_size);
-    bar_banner_ripple_->SetPosition(gfx::PointF(ripple_left, 0.f));
-    bar_banner_ripple_->SetOpacity(search_bar_banner_ripple_opacity);
-
-    if (ripple_rotation != 0.f) {
-      // Apply rotation about the center of the resource.
-      float pivot_x = floor(bar_banner_ripple_size.width() / 2);
-      float pivot_y = floor(bar_banner_ripple_size.height() / 2);
-      gfx::PointF pivot_origin(pivot_x, pivot_y);
-      gfx::Transform transform;
-      transform.Translate(pivot_origin.x(), pivot_origin.y());
-      transform.RotateAboutZAxis(ripple_rotation);
-      transform.Translate(-pivot_origin.x(), -pivot_origin.y());
-      bar_banner_ripple_->SetTransform(transform);
-    }
-
-    // -----------------------------------------------------------------
-    // Bar Banner Text
-    // -----------------------------------------------------------------
-    if (bar_banner_text_resource) {
-      bar_banner_text_->SetUIResourceId(
-          bar_banner_text_resource->ui_resource()->id());
-      bar_banner_text_->SetBounds(bar_banner_text_resource->size());
-      bar_banner_text_->SetPosition(
-          gfx::PointF(0.f, search_bar_banner_padding));
-      bar_banner_text_->SetOpacity(search_bar_banner_text_opacity);
-    }
-  } else {
-    // Bar Banner Container
-    if (bar_banner_container_.get() && bar_banner_container_->parent())
-      bar_banner_container_->RemoveFromParent();
-  }
-
   // ---------------------------------------------------------------------------
   // Search Term, Context and Search Caption
   // ---------------------------------------------------------------------------
@@ -702,22 +600,9 @@
       search_promo_container_(cc::SolidColorLayer::Create()),
       related_searches_in_bar_(cc::UIResourceLayer::Create()),
       related_searches_in_content_(cc::UIResourceLayer::Create()),
-      bar_banner_container_(cc::SolidColorLayer::Create()),
-      bar_banner_ripple_(cc::NinePatchLayer::Create()),
-      bar_banner_text_(cc::UIResourceLayer::Create()),
       search_caption_(cc::UIResourceLayer::Create()),
       text_layer_(cc::UIResourceLayer::Create()),
       touch_highlight_layer_(cc::SolidColorLayer::Create()) {
-  // Search Bar Banner
-  bar_banner_container_->SetIsDrawable(true);
-  bar_banner_container_->SetBackgroundColor(
-      SkColor4f::FromColor(kSearchBarBackgroundColor));
-  bar_banner_ripple_->SetIsDrawable(true);
-  bar_banner_ripple_->SetFillCenter(true);
-  bar_banner_text_->SetIsDrawable(true);
-  bar_banner_container_->AddChild(bar_banner_ripple_);
-  bar_banner_container_->AddChild(bar_banner_text_);
-
   // Search Bar Text
   search_context_->SetIsDrawable(true);
 
diff --git a/chrome/browser/android/compositor/layer/contextual_search_layer.h b/chrome/browser/android/compositor/layer/contextual_search_layer.h
index afa2950..99e4c97 100644
--- a/chrome/browser/android/compositor/layer/contextual_search_layer.h
+++ b/chrome/browser/android/compositor/layer/contextual_search_layer.h
@@ -9,7 +9,6 @@
 
 namespace cc {
 class Layer;
-class NinePatchLayer;
 class SolidColorLayer;
 class UIResourceLayer;
 }
@@ -49,8 +48,6 @@
                      int progress_bar_resource_id,
                      int progress_bar_tint,
                      int search_promo_resource_id,
-                     int bar_banner_ripple_resource_id,
-                     int bar_banner_text_resource_id,
                      float dp_to_px,
                      const scoped_refptr<cc::Layer>& content_layer,
                      bool search_promo_visible,
@@ -65,13 +62,7 @@
                      bool related_searches_in_bar_visible,
                      float related_searches_in_bar_height,
                      float related_searches_in_bar_redundant_padding,
-                     // Banner etc
-                     bool search_bar_banner_visible,
-                     float search_bar_banner_height,
-                     float search_bar_banner_padding,
-                     float search_bar_banner_ripple_width,
-                     float search_bar_banner_ripple_opacity,
-                     float search_bar_banner_text_opacity,
+                     // Panel position etc
                      float search_panel_x,
                      float search_panel_y,
                      float search_panel_width,
@@ -152,9 +143,6 @@
   scoped_refptr<cc::SolidColorLayer> search_promo_container_;
   scoped_refptr<cc::UIResourceLayer> related_searches_in_bar_;
   scoped_refptr<cc::UIResourceLayer> related_searches_in_content_;
-  scoped_refptr<cc::SolidColorLayer> bar_banner_container_;
-  scoped_refptr<cc::NinePatchLayer> bar_banner_ripple_;
-  scoped_refptr<cc::UIResourceLayer> bar_banner_text_;
   scoped_refptr<cc::UIResourceLayer> search_caption_;
   scoped_refptr<cc::UIResourceLayer> text_layer_;
   scoped_refptr<cc::SolidColorLayer> touch_highlight_layer_;
diff --git a/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.cc
index 5c026a6..ef74036 100644
--- a/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.cc
@@ -83,8 +83,6 @@
     jint progress_bar_resource_id,
     jint progress_bar_tint,
     jint search_promo_resource_id,
-    jint bar_banner_ripple_resource_id,
-    jint bar_banner_text_resource_id,
     jfloat dp_to_px,
     jfloat layout_width,
     jfloat layout_height,
@@ -103,13 +101,7 @@
     jboolean related_searches_in_bar_visible,
     jfloat related_searches_in_bar_height,
     jfloat related_searches_in_bar_redundant_padding,
-    // Banner etc
-    jboolean search_bar_banner_visible,
-    jfloat search_bar_banner_height,
-    jfloat search_bar_banner_padding,
-    jfloat search_bar_banner_ripple_width,
-    jfloat search_bar_banner_ripple_opacity,
-    jfloat search_bar_banner_text_opacity,
+    // Panel position etc
     jfloat search_panel_x,
     jfloat search_panel_y,
     jfloat search_panel_width,
@@ -176,19 +168,14 @@
       drag_handlebar_resource_id, open_tab_icon_resource_id,
       close_icon_resource_id, progress_bar_background_resource_id,
       progress_bar_background_tint, progress_bar_resource_id, progress_bar_tint,
-      search_promo_resource_id, bar_banner_ripple_resource_id,
-      bar_banner_text_resource_id, dp_to_px, content_layer,
-      search_promo_visible, search_promo_height, search_promo_opacity,
-      search_promo_background_color,
+      search_promo_resource_id, dp_to_px, content_layer, search_promo_visible,
+      search_promo_height, search_promo_opacity, search_promo_background_color,
       // Related Searches
       related_searches_in_content_resource_id,
       related_searches_in_content_visible, related_searches_in_content_height,
       related_searches_in_bar_resource_id, related_searches_in_bar_visible,
       related_searches_in_bar_height, related_searches_in_bar_redundant_padding,
-      // Banner etc
-      search_bar_banner_visible, search_bar_banner_height,
-      search_bar_banner_padding, search_bar_banner_ripple_width,
-      search_bar_banner_ripple_opacity, search_bar_banner_text_opacity,
+      // Panel position etc
       search_panel_x, search_panel_y, search_panel_width, search_panel_height,
       search_bar_margin_side, search_bar_margin_top, search_bar_height,
       search_context_opacity, search_text_layer_min_height, search_term_opacity,
diff --git a/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h b/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h
index b7c727f..51fe79d 100644
--- a/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h
+++ b/chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h
@@ -64,8 +64,6 @@
       jint progress_bar_resource_id,
       jint progress_bar_tint,
       jint search_promo_resource_id,
-      jint bar_banner_ripple_resource_id,
-      jint bar_banner_text_resource_id,
       jfloat dp_to_px,
       jfloat layout_width,
       jfloat layout_height,
@@ -84,13 +82,7 @@
       jboolean related_searches_in_bar_visible,
       jfloat related_searches_in_bar_height,
       jfloat related_searches_in_bar_redundant_padding,
-      // Banner etc
-      jboolean search_bar_banner_visible,
-      jfloat search_bar_banner_height,
-      jfloat search_bar_banner_padding,
-      jfloat search_bar_banner_ripple_width,
-      jfloat search_bar_banner_ripple_opacity,
-      jfloat search_bar_banner_text_opacity,
+      // Panel position etc
       jfloat search_panel_x,
       jfloat search_panel_y,
       jfloat search_panel_width,
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index c2706baf..e0dbbf5 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -102,7 +102,8 @@
   if (!web_contents)
     return;
 
-  ukm::SourceId source_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   ukm::builders::Webapp_AddToHomeScreen(source_id)
       .SetDisplayMode(static_cast<int>(info.display))
       .SetShortcutReason(static_cast<int>(installable_status))
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index ea690d6..262e1509 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -349,7 +349,7 @@
   // during shutdown. See https://codereview.chromium.org/146693011/
   // and http://crbug.com/338709 for details.
   content::RenderProcessHost* process =
-      web_contents()->GetMainFrame()->GetProcess();
+      web_contents()->GetPrimaryMainFrame()->GetProcess();
   if (process)
     process->FastShutdownIfPossible(1, false);
 
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
index f9f4bee..e95c473 100644
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -638,7 +638,7 @@
   content::WebContents* web_contents =
       content::WebContents::FromJavaWebContents(java_web_contents);
   if (base::RandDouble() < 0.01)
-    web_contents->GetMainFrame()->GetProcess()->DumpProcessStack();
+    web_contents->GetPrimaryMainFrame()->GetProcess()->DumpProcessStack();
 
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableHungRendererInfoBar)) {
@@ -649,7 +649,7 @@
       infobars::ContentInfoBarManager::FromWebContents(web_contents);
   DCHECK(!FindHungRendererInfoBar(infobar_manager));
   HungRendererInfoBarDelegate::Create(
-      infobar_manager, web_contents->GetMainFrame()->GetProcess());
+      infobar_manager, web_contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 void JNI_TabWebContentsDelegateAndroidImpl_OnRendererResponsive(
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc
index 72e4aef..48d04093 100644
--- a/chrome/browser/android/webapk/webapk_installer.cc
+++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -281,7 +281,7 @@
       DVLOG(1) << "The WebAPK installation failed.";
       webapk::TrackInstallEvent(webapk::INSTALL_FAILED);
       if (web_contents_ && !web_contents_->IsBeingDestroyed()) {
-        web_contents_->GetMainFrame()->AddMessageToConsole(
+        web_contents_->GetPrimaryMainFrame()->AddMessageToConsole(
             blink::mojom::ConsoleMessageLevel::kError,
             base::StringPrintf(kWebApkFailureMessageTemplate,
                                manifest_url_.spec().c_str()));
diff --git a/chrome/browser/apps/app_service/media_access_browsertest.cc b/chrome/browser/apps/app_service/media_access_browsertest.cc
index 4af0815..3bc54886 100644
--- a/chrome/browser/apps/app_service/media_access_browsertest.cc
+++ b/chrome/browser/apps/app_service/media_access_browsertest.cc
@@ -104,8 +104,8 @@
                                      blink::mojom::MediaStreamType stream_type,
                                      content::MediaRequestState state) {
   ASSERT_TRUE(web_content);
-  MediaRequestChange(web_content->GetMainFrame()->GetProcess()->GetID(),
-                     web_content->GetMainFrame()->GetRoutingID(), url,
+  MediaRequestChange(web_content->GetPrimaryMainFrame()->GetProcess()->GetID(),
+                     web_content->GetPrimaryMainFrame()->GetRoutingID(), url,
                      stream_type, state);
 }
 
@@ -205,8 +205,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser1, GetUrl1()));
   content::WebContents* web_content1 =
       browser1->tab_strip_model()->GetActiveWebContents();
-  int render_process_id1 = web_content1->GetMainFrame()->GetProcess()->GetID();
-  int render_frame_id1 = web_content1->GetMainFrame()->GetRoutingID();
+  int render_process_id1 =
+      web_content1->GetPrimaryMainFrame()->GetProcess()->GetID();
+  int render_frame_id1 = web_content1->GetPrimaryMainFrame()->GetRoutingID();
   // Request accessing the camera and the microphone for |web_content1|.
   MediaRequestChangeForWebContent(
       web_content1, GetUrl1(),
@@ -225,8 +226,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser1, GetUrl2()));
   content::WebContents* web_content2 =
       browser1->tab_strip_model()->GetActiveWebContents();
-  int render_process_id2 = web_content2->GetMainFrame()->GetProcess()->GetID();
-  int render_frame_id2 = web_content2->GetMainFrame()->GetRoutingID();
+  int render_process_id2 =
+      web_content2->GetPrimaryMainFrame()->GetProcess()->GetID();
+  int render_frame_id2 = web_content2->GetPrimaryMainFrame()->GetRoutingID();
   // Request accessing the camera and the microphone for |web_content2|.
   MediaRequestChangeForWebContent(
       web_content2, GetUrl2(),
@@ -488,8 +490,9 @@
 
   // Request accessing the camera for |app_id| in the new tab.
   content::WebContents* web_content1 = GetWebContents();
-  int render_process_id1 = web_content1->GetMainFrame()->GetProcess()->GetID();
-  int render_frame_id1 = web_content1->GetMainFrame()->GetRoutingID();
+  int render_process_id1 =
+      web_content1->GetPrimaryMainFrame()->GetProcess()->GetID();
+  int render_frame_id1 = web_content1->GetPrimaryMainFrame()->GetRoutingID();
   MediaRequestChangeForWebContent(
       web_content1, GetUrl1(),
       blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE,
@@ -498,8 +501,9 @@
 
   // Launch |app_id| in a new window.
   content::WebContents* web_content2 = OpenApplication(app_id);
-  int render_process_id2 = web_content2->GetMainFrame()->GetProcess()->GetID();
-  int render_frame_id2 = web_content2->GetMainFrame()->GetRoutingID();
+  int render_process_id2 =
+      web_content2->GetPrimaryMainFrame()->GetProcess()->GetID();
+  int render_frame_id2 = web_content2->GetPrimaryMainFrame()->GetRoutingID();
   Browser* app_browser = BrowserList::GetInstance()->GetLastActive();
   ASSERT_TRUE(app_browser);
   ASSERT_NE(browser(), app_browser);
diff --git a/chrome/browser/apps/guest_view/app_view_browsertest.cc b/chrome/browser/apps/guest_view/app_view_browsertest.cc
index 24af8a0..46172817 100644
--- a/chrome/browser/apps/guest_view/app_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/app_view_browsertest.cc
@@ -183,7 +183,7 @@
       extensions::AppWindowRegistry::Get(browser()->profile())
           ->GetCurrentAppWindowForApp(bad_app->id())
           ->web_contents()
-          ->GetMainFrame()
+          ->GetPrimaryMainFrame()
           ->GetProcess();
 
   // Monitor |bad_app|'s RenderProcessHost for its exiting.
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 18dcd36c..a3f0418 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -357,7 +357,7 @@
     mouse_event_.SetPositionInScreen(point.x() + offset.x(),
                                      point.y() + offset.y());
     mouse_event_.click_count = 1;
-    web_contents_->GetMainFrame()
+    web_contents_->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->ForwardMouseEvent(mouse_event_);
@@ -380,7 +380,7 @@
  private:
   void SendMouseUp() {
     mouse_event_.SetType(blink::WebInputEvent::Type::kMouseUp);
-    web_contents_->GetMainFrame()
+    web_contents_->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->ForwardMouseEvent(mouse_event_);
@@ -740,7 +740,7 @@
     content::Source<content::NavigationController> source =
         guest_observer.source();
     EXPECT_TRUE(source->DeprecatedGetWebContents()
-                    ->GetMainFrame()
+                    ->GetPrimaryMainFrame()
                     ->GetProcess()
                     ->IsForGuestsOnly());
 
@@ -780,8 +780,9 @@
     // Wait for interstitial page to be shown in guest.
     content::WebContents* guest_web_contents =
         GetGuestViewManager()->WaitForSingleGuestCreated();
-    ASSERT_TRUE(
-        guest_web_contents->GetMainFrame()->GetProcess()->IsForGuestsOnly());
+    ASSERT_TRUE(guest_web_contents->GetPrimaryMainFrame()
+                    ->GetProcess()
+                    ->IsForGuestsOnly());
     GURL target_url = https_server.GetURL(
         "/extensions/platform_apps/web_view/interstitial_teardown/"
         "https_page.html");
@@ -852,12 +853,12 @@
         blink::WebInputEvent::GetStaticTimeStampForTests());
     mouse_event.button = blink::WebMouseEvent::Button::kRight;
     mouse_event.SetPositionInWidget(1, 1);
-    web_contents->GetMainFrame()
+    web_contents->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->ForwardMouseEvent(mouse_event);
     mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-    web_contents->GetMainFrame()
+    web_contents->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->ForwardMouseEvent(mouse_event);
@@ -1643,8 +1644,8 @@
   content::WebContents* guest1 = guest_contents_list[0];
   content::WebContents* guest2 = guest_contents_list[1];
   ASSERT_NE(guest1, guest2);
-  auto* guest_instance1 = guest1->GetMainFrame()->GetSiteInstance();
-  auto* guest_instance2 = guest2->GetMainFrame()->GetSiteInstance();
+  auto* guest_instance1 = guest1->GetPrimaryMainFrame()->GetSiteInstance();
+  auto* guest_instance2 = guest2->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(guest_instance1->IsGuest());
   EXPECT_TRUE(guest_instance2->IsGuest());
   EXPECT_EQ(guest_instance1->GetStoragePartitionConfig(),
@@ -1681,8 +1682,8 @@
   content::WebContents* guest1 = guest_contents_list[0];
   content::WebContents* guest2 = guest_contents_list[1];
   ASSERT_NE(guest1, guest2);
-  auto* guest_instance1 = guest1->GetMainFrame()->GetSiteInstance();
-  auto* guest_instance2 = guest2->GetMainFrame()->GetSiteInstance();
+  auto* guest_instance1 = guest1->GetPrimaryMainFrame()->GetSiteInstance();
+  auto* guest_instance2 = guest2->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(guest_instance1->IsGuest());
   EXPECT_TRUE(guest_instance2->IsGuest());
   EXPECT_EQ(guest_instance1->GetStoragePartitionConfig(),
@@ -1741,7 +1742,7 @@
   content::Source<content::NavigationController> source =
       empty_guest_observer.source();
   EXPECT_TRUE(source->DeprecatedGetWebContents()
-                  ->GetMainFrame()
+                  ->GetPrimaryMainFrame()
                   ->GetProcess()
                   ->IsForGuestsOnly());
   ASSERT_TRUE(done_listener.WaitUntilSatisfied());
@@ -1765,9 +1766,9 @@
   ASSERT_TRUE(empty_guest_embedder);
   content::RenderFrameHost* empty_guest_opener =
       empty_guest_web_contents->GetFirstWebContentsInLiveOriginalOpenerChain()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
   ASSERT_TRUE(empty_guest_opener);
-  ASSERT_NE(empty_guest_opener, empty_guest_embedder->GetMainFrame());
+  ASSERT_NE(empty_guest_opener, empty_guest_embedder->GetPrimaryMainFrame());
 }
 
 // This is a regression test for crbug.com/1309302. It launches an app
@@ -1955,11 +1956,12 @@
           ? guest_contents_list[1]
           : guest_contents_list[0];
 
-  content::RenderFrameHost* embedder_main_frame = embedder->GetMainFrame();
+  content::RenderFrameHost* embedder_main_frame =
+      embedder->GetPrimaryMainFrame();
   content::RenderFrameHost* unattached_guest_main_frame =
-      unattached_guest->web_contents()->GetMainFrame();
+      unattached_guest->web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* other_guest_main_frame =
-      other_guest->GetMainFrame();
+      other_guest->GetPrimaryMainFrame();
 
   EXPECT_THAT(
       content::CollectAllRenderFrameHosts(embedder_main_frame),
@@ -2121,7 +2123,7 @@
   content::Source<content::NavigationController> source =
       guest_observer.source();
   EXPECT_TRUE(source->DeprecatedGetWebContents()
-                  ->GetMainFrame()
+                  ->GetPrimaryMainFrame()
                   ->GetProcess()
                   ->IsForGuestsOnly());
 
@@ -2205,7 +2207,8 @@
   std::vector<content::RenderWidgetHostView*> hosts =
       content::GetInputEventRouterRenderWidgetHostViews(web_contents);
 
-  EXPECT_TRUE(base::Contains(hosts, web_contents->GetMainFrame()->GetView()));
+  EXPECT_TRUE(
+      base::Contains(hosts, web_contents->GetPrimaryMainFrame()->GetView()));
 }
 
 // Test makes sure that the browser does not crash when a <webview> navigates
@@ -2352,8 +2355,9 @@
     // Wait for guest navigation to complete.
     auto* guest_web_contents =
         GetGuestViewManager()->WaitForSingleGuestCreated();
-    ASSERT_TRUE(
-        guest_web_contents->GetMainFrame()->GetProcess()->IsForGuestsOnly());
+    ASSERT_TRUE(guest_web_contents->GetPrimaryMainFrame()
+                    ->GetProcess()
+                    ->IsForGuestsOnly());
     observer.WatchExistingWebContents();
     observer.WaitForNavigationFinished();
   }
@@ -2774,7 +2778,8 @@
   ASSERT_TRUE(guest_web_contents);
 
   content::ContextMenuParams params;
-  TestRenderViewContextMenu menu(*guest_web_contents->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*guest_web_contents->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   // Expect "Inspect" to be shown as we are running webview in a chrome app.
@@ -3718,12 +3723,13 @@
   // Retrive the guestProcessId and guestRenderFrameRoutingId from the
   // extension.
   int guest_process_id =
-      content::ExecuteScriptAndGetValue(embedder_web_contents->GetMainFrame(),
-                                        "window.guestProcessId")
+      content::ExecuteScriptAndGetValue(
+          embedder_web_contents->GetPrimaryMainFrame(), "window.guestProcessId")
           .GetInt();
   int guest_render_frame_routing_id =
-      content::ExecuteScriptAndGetValue(embedder_web_contents->GetMainFrame(),
-                                        "window.guestRenderFrameRoutingId")
+      content::ExecuteScriptAndGetValue(
+          embedder_web_contents->GetPrimaryMainFrame(),
+          "window.guestRenderFrameRoutingId")
           .GetInt();
 
   auto* guest_rfh = content::RenderFrameHost::FromID(
@@ -3896,7 +3902,7 @@
     content::WebContents* guest =
         GetGuestViewManager()->WaitForSingleGuestCreated();
     ASSERT_TRUE(guest);
-    content::RenderFrameHost* main_frame = guest->GetMainFrame();
+    content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
     EXPECT_TRUE(main_frame->GetSiteInstance()->RequiresDedicatedProcess());
     EXPECT_TRUE(main_frame->GetProcess()->IsProcessLockedToSiteForTesting());
 
@@ -4192,7 +4198,10 @@
   Profile* profile = browser()->profile();
   int rules_registry_id =
       extensions::WebViewGuest::GetOrGenerateRulesRegistryID(
-          guest->owner_web_contents()->GetMainFrame()->GetProcess()->GetID(),
+          guest->owner_web_contents()
+              ->GetPrimaryMainFrame()
+              ->GetProcess()
+              ->GetID(),
           guest->view_instance_id());
 
   extensions::RulesRegistryService* registry_service =
@@ -4206,8 +4215,10 @@
       registry_service->GetRulesRegistry(rules_registry_id, "ui").get());
 
   // Kill the embedder's render process, so the webview will go as well.
-  embedder_web_contents->GetMainFrame()->GetProcess()->GetProcess().Terminate(
-      0, false);
+  embedder_web_contents->GetPrimaryMainFrame()
+      ->GetProcess()
+      ->GetProcess()
+      .Terminate(0, false);
   observer->WaitForEmbedderRenderProcessTerminate();
 
   EXPECT_FALSE(
@@ -4234,7 +4245,10 @@
       extensions::RulesRegistryService::Get(profile);
   int rules_registry_id =
       extensions::WebViewGuest::GetOrGenerateRulesRegistryID(
-          guest->owner_web_contents()->GetMainFrame()->GetProcess()->GetID(),
+          guest->owner_web_contents()
+              ->GetPrimaryMainFrame()
+              ->GetProcess()
+              ->GetID(),
           guest->view_instance_id());
 
   // Get an existing registered rule for the guest.
@@ -4367,8 +4381,8 @@
   // Open a context menu for the MimeHandlerViewGuest. Since the <webview> can
   // navigate back, the Back item should be enabled.
   content::ContextMenuParams params;
-  TestRenderViewContextMenu menu(*mime_handler_view_contents->GetMainFrame(),
-                                 params);
+  TestRenderViewContextMenu menu(
+      *mime_handler_view_contents->GetPrimaryMainFrame(), params);
   menu.Init();
   ASSERT_TRUE(menu.IsCommandIdEnabled(IDC_BACK));
 
@@ -4431,7 +4445,7 @@
   EXPECT_TRUE(guest_url.SchemeIs(extensions::kExtensionScheme));
 
   auto* process_map = extensions::ProcessMap::Get(guest->GetBrowserContext());
-  auto* guest_process = guest->GetMainFrame()->GetProcess();
+  auto* guest_process = guest->GetPrimaryMainFrame()->GetProcess();
   EXPECT_FALSE(process_map->Contains(guest_process->GetID()));
   EXPECT_TRUE(
       process_map->GetExtensionsInProcess(guest_process->GetID()).empty());
@@ -4482,7 +4496,8 @@
 
   EXPECT_EQ(webview_url, web_view_contents->GetLastCommittedURL());
 
-  content::RenderFrameHost* main_frame = web_view_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      web_view_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* blob_frame = ChildFrameAt(main_frame, 0);
   EXPECT_TRUE(blob_frame->GetLastCommittedURL().SchemeIsBlob());
 
@@ -4533,24 +4548,24 @@
 IN_PROC_BROWSER_TEST_P(WebViewTest, ReloadAfterCrash) {
   // Load guest and wait for it to appear.
   LoadAppWithGuest("web_view/simple");
-  EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView());
+  EXPECT_TRUE(GetGuestWebContents()->GetPrimaryMainFrame()->GetView());
   content::RenderFrameSubmissionObserver frame_observer(GetGuestWebContents());
   frame_observer.WaitForMetadataChange();
 
   // Kill guest.
-  auto* rph = GetGuestWebContents()->GetMainFrame()->GetProcess();
+  auto* rph = GetGuestWebContents()->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   EXPECT_TRUE(rph->Shutdown(content::RESULT_CODE_KILLED));
   crash_observer.Wait();
-  EXPECT_FALSE(GetGuestWebContents()->GetMainFrame()->GetView());
+  EXPECT_FALSE(GetGuestWebContents()->GetPrimaryMainFrame()->GetView());
 
   // Reload guest and make sure it appears.
   content::TestNavigationObserver load_observer(GetGuestWebContents());
   EXPECT_TRUE(ExecuteScript(GetEmbedderWebContents(),
                             "document.querySelector('webview').reload()"));
   load_observer.Wait();
-  EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView());
+  EXPECT_TRUE(GetGuestWebContents()->GetPrimaryMainFrame()->GetView());
   // Ensure that the guest produces a new frame.
   frame_observer.WaitForAnyFrameSubmission();
 }
@@ -4756,7 +4771,7 @@
       blink::WebInputEvent::kIsTouchAccessibility,
       blink::WebInputEvent::GetStaticTimeStampForTests());
   accessibility_touch_event.SetPositionInWidget(95, 55);
-  web_contents->GetMainFrame()
+  web_contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardMouseEvent(accessibility_touch_event);
@@ -4934,7 +4949,7 @@
                                 ui::LatencyInfo(ui::SourceEventType::WHEEL));
 
   content::InputEventAckWaiter update_waiter(
-      guest_contents->GetMainFrame()->GetRenderViewHost()->GetWidget(),
+      guest_contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget(),
       base::BindRepeating([](blink::mojom::InputEventResultSource,
                              blink::mojom::InputEventResultState state,
                              const blink::WebInputEvent& event) {
@@ -5136,11 +5151,11 @@
   auto pending =
       content::GetRenderFrameHostsWithPendingFindResults(embedder_web_contents);
   // Request for main frame of the tab.
-  EXPECT_EQ(1U, pending.count(embedder_web_contents->GetMainFrame()));
+  EXPECT_EQ(1U, pending.count(embedder_web_contents->GetPrimaryMainFrame()));
   // Request for main frame of the attached guest.
-  EXPECT_EQ(1U, pending.count(attached_guest->GetMainFrame()));
+  EXPECT_EQ(1U, pending.count(attached_guest->GetPrimaryMainFrame()));
   // No request for the unattached guest.
-  EXPECT_EQ(0U, pending.count(unattached_guest->GetMainFrame()));
+  EXPECT_EQ(0U, pending.count(unattached_guest->GetPrimaryMainFrame()));
   // Sanity-check: try the set returned for guest.
   pending =
       content::GetRenderFrameHostsWithPendingFindResults(unattached_guest);
@@ -5194,7 +5209,7 @@
     load_observer.Wait();
   }
 
-  EXPECT_TRUE(guest->GetMainFrame()->GetSiteInstance()->IsGuest());
+  EXPECT_TRUE(guest->GetPrimaryMainFrame()->GetSiteInstance()->IsGuest());
 
   // Now, navigate <webview> to a regular page with a subframe.
   GURL foo_url(embedded_test_server()->GetURL("foo.com", "/iframe.html"));
@@ -5212,17 +5227,17 @@
   // guest process and SiteInstance.  Otherwise, it will be in its own
   // SiteInstance and process.
   content::RenderFrameHost* webview_subframe =
-      ChildFrameAt(guest->GetMainFrame(), 0);
+      ChildFrameAt(guest->GetPrimaryMainFrame(), 0);
   if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()) {
     EXPECT_NE(webview_subframe->GetProcess(),
-              guest->GetMainFrame()->GetProcess());
+              guest->GetPrimaryMainFrame()->GetProcess());
     EXPECT_NE(webview_subframe->GetSiteInstance(),
-              guest->GetMainFrame()->GetSiteInstance());
+              guest->GetPrimaryMainFrame()->GetSiteInstance());
   } else {
     EXPECT_EQ(webview_subframe->GetProcess(),
-              guest->GetMainFrame()->GetProcess());
+              guest->GetPrimaryMainFrame()->GetProcess());
     EXPECT_EQ(webview_subframe->GetSiteInstance(),
-              guest->GetMainFrame()->GetSiteInstance());
+              guest->GetPrimaryMainFrame()->GetSiteInstance());
   }
 
   // Load a page with subframe in a regular tab.
@@ -5234,11 +5249,12 @@
   // WebView process, which has isolated.foo.com committed in a different
   // storage partition.
   EXPECT_TRUE(NavigateIframeToURL(tab, "test", isolated_url));
-  content::RenderFrameHost* subframe = ChildFrameAt(tab->GetMainFrame(), 0);
-  EXPECT_NE(guest->GetMainFrame()->GetProcess(), subframe->GetProcess());
+  content::RenderFrameHost* subframe =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
+  EXPECT_NE(guest->GetPrimaryMainFrame()->GetProcess(), subframe->GetProcess());
 
   // Check that the guest process hasn't crashed.
-  EXPECT_TRUE(guest->GetMainFrame()->IsRenderFrameLive());
+  EXPECT_TRUE(guest->GetPrimaryMainFrame()->IsRenderFrameLive());
 
   // Check that accessing a foo.com cookie from the WebView doesn't result in a
   // renderer kill. This might happen if we erroneously applied an isolated.com
@@ -5272,8 +5288,9 @@
   GURL isolated_url(
       embedded_test_server()->GetURL("isolated.com", "/title1.html"));
   EXPECT_TRUE(NavigateIframeToURL(tab, "test", isolated_url));
-  content::RenderFrameHost* subframe = ChildFrameAt(tab->GetMainFrame(), 0);
-  EXPECT_NE(tab->GetMainFrame()->GetProcess(), subframe->GetProcess());
+  content::RenderFrameHost* subframe =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
+  EXPECT_NE(tab->GetPrimaryMainFrame()->GetProcess(), subframe->GetProcess());
 
   // Navigate <webview> to a regular page with an isolated origin subframe.
   {
@@ -5288,17 +5305,17 @@
   // guest process and SiteInstance.  Otherwise, it will be in its own
   // SiteInstance and process.
   content::RenderFrameHost* webview_subframe =
-      ChildFrameAt(guest->GetMainFrame(), 0);
+      ChildFrameAt(guest->GetPrimaryMainFrame(), 0);
   if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()) {
     EXPECT_NE(webview_subframe->GetProcess(),
-              guest->GetMainFrame()->GetProcess());
+              guest->GetPrimaryMainFrame()->GetProcess());
     EXPECT_NE(webview_subframe->GetSiteInstance(),
-              guest->GetMainFrame()->GetSiteInstance());
+              guest->GetPrimaryMainFrame()->GetSiteInstance());
   } else {
     EXPECT_EQ(webview_subframe->GetProcess(),
-              guest->GetMainFrame()->GetProcess());
+              guest->GetPrimaryMainFrame()->GetProcess());
     EXPECT_EQ(webview_subframe->GetSiteInstance(),
-              guest->GetMainFrame()->GetSiteInstance());
+              guest->GetPrimaryMainFrame()->GetSiteInstance());
   }
 
   // The isolated origin subframe in <webview> shouldn't share the process with
@@ -5306,8 +5323,8 @@
   EXPECT_NE(webview_subframe->GetProcess(), subframe->GetProcess());
 
   // Check that the guest and regular tab processes haven't crashed.
-  EXPECT_TRUE(guest->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_TRUE(tab->GetMainFrame()->IsRenderFrameLive());
+  EXPECT_TRUE(guest->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_TRUE(tab->GetPrimaryMainFrame()->IsRenderFrameLive());
   EXPECT_TRUE(subframe->IsRenderFrameLive());
 
   // Check that accessing a foo.com cookie from the WebView doesn't result in a
@@ -5508,7 +5525,7 @@
   // URL.
   EXPECT_FALSE(load_observer.last_navigation_succeeded());
   content::RenderFrameHost* webview_subframe =
-      ChildFrameAt(guest->GetMainFrame(), 0);
+      ChildFrameAt(guest->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(webview_subframe->GetLastCommittedURL(), iframe_url);
 
   // Check that a proper UKM event was logged for failed extension file access.
@@ -5626,7 +5643,7 @@
   EXPECT_FALSE(error_observer.last_navigation_succeeded());
   EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, error_observer.last_net_error_code());
 
-  content::RenderFrameHost* guest_rfh = guest->GetMainFrame();
+  content::RenderFrameHost* guest_rfh = guest->GetPrimaryMainFrame();
   EXPECT_TRUE(guest_rfh->IsRenderFrameLive());
 
   // Double-check that after the attempted navigation the <webview> is not
@@ -5671,7 +5688,7 @@
   ASSERT_TRUE(guest);
 
   // Ensure the <webview>'s SiteInstance is for a guest.
-  content::RenderFrameHost* main_frame = guest->GetMainFrame();
+  content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
   auto original_id = main_frame->GetGlobalId();
   scoped_refptr<content::SiteInstance> starting_instance =
       main_frame->GetSiteInstance();
@@ -5691,7 +5708,7 @@
 
   // Expect that the main frame swapped SiteInstances and RenderFrameHosts but
   // stayed in the same BrowsingInstance and StoragePartition.
-  main_frame = guest->GetMainFrame();
+  main_frame = guest->GetPrimaryMainFrame();
   EXPECT_TRUE(main_frame->GetSiteInstance()->IsGuest());
   EXPECT_TRUE(main_frame->GetProcess()->IsForGuestsOnly());
   EXPECT_NE(main_frame->GetGlobalId(), original_id);
@@ -5747,7 +5764,7 @@
   ASSERT_TRUE(guest);
 
   scoped_refptr<content::SiteInstance> first_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(first_instance->IsGuest());
 
   // Navigate <webview> to an error page.
@@ -5760,13 +5777,13 @@
       ExecuteScript(guest, "location.href = '" + error_url.spec() + "';"));
   load_observer.Wait();
   EXPECT_FALSE(load_observer.last_navigation_succeeded());
-  EXPECT_TRUE(guest->GetMainFrame()->IsErrorDocument());
+  EXPECT_TRUE(guest->GetPrimaryMainFrame()->IsErrorDocument());
 
   // The error page's SiteInstance should require a dedicated process due to
   // error page isolation, but it should still be considered a guest and should
   // stay in the guest's StoragePartition.
   scoped_refptr<content::SiteInstance> error_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(error_instance->RequiresDedicatedProcess());
   EXPECT_NE(error_instance, first_instance);
   EXPECT_TRUE(error_instance->IsGuest());
@@ -5777,8 +5794,8 @@
   // embedder-initiated navigation to an error page.
   EXPECT_TRUE(NavigateToURL(
       guest, embedded_test_server()->GetURL("b.test", "/iframe.html")));
-  EXPECT_FALSE(guest->GetMainFrame()->IsErrorDocument());
-  EXPECT_NE(guest->GetMainFrame()->GetSiteInstance(), error_instance);
+  EXPECT_FALSE(guest->GetPrimaryMainFrame()->IsErrorDocument());
+  EXPECT_NE(guest->GetPrimaryMainFrame()->GetSiteInstance(), error_instance);
 
   content::WebContents* embedder = GetEmbedderWebContents();
   {
@@ -5788,11 +5805,11 @@
         "document.querySelector('webview').src = '" + error_url.spec() + "';"));
     load_observer.Wait();
     EXPECT_FALSE(load_observer.last_navigation_succeeded());
-    EXPECT_TRUE(guest->GetMainFrame()->IsErrorDocument());
+    EXPECT_TRUE(guest->GetPrimaryMainFrame()->IsErrorDocument());
   }
 
   scoped_refptr<content::SiteInstance> second_error_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(second_error_instance->RequiresDedicatedProcess());
   EXPECT_TRUE(second_error_instance->IsGuest());
   EXPECT_EQ(first_instance->GetStoragePartitionConfig(),
@@ -5826,7 +5843,7 @@
     load_observer.Wait();
   }
   scoped_refptr<content::SiteInstance> first_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(first_instance->IsGuest());
   EXPECT_TRUE(first_instance->GetProcess()->IsForGuestsOnly());
 
@@ -5836,7 +5853,7 @@
       embedded_test_server()->GetURL("b.test", "/title1.html");
   EXPECT_TRUE(NavigateToURL(guest, second_url));
   scoped_refptr<content::SiteInstance> second_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
 
   // Ensure that a new unrelated guest SiteInstance was created, and that the
   // StoragePartition didn't change.
@@ -5910,7 +5927,7 @@
   content::WebContents* guest = GetGuestWebContents();
   ASSERT_TRUE(guest);
   scoped_refptr<content::SiteInstance> first_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(first_instance->IsGuest());
   EXPECT_TRUE(first_instance->GetProcess()->IsForGuestsOnly());
 
@@ -5919,7 +5936,7 @@
   const GURL blank_url(url::kAboutBlankURL);
   EXPECT_TRUE(content::NavigateToURLFromRenderer(guest, blank_url));
   scoped_refptr<content::SiteInstance> second_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_EQ(first_instance, second_instance);
 
   // Navigate <webview> away to another page.  This should swap
@@ -5928,7 +5945,7 @@
       embedded_test_server()->GetURL("b.test", "/title1.html");
   EXPECT_TRUE(NavigateToURL(guest, second_url));
   scoped_refptr<content::SiteInstance> third_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(third_instance->IsGuest());
   EXPECT_TRUE(third_instance->GetProcess()->IsForGuestsOnly());
   EXPECT_NE(first_instance, third_instance);
@@ -5949,7 +5966,7 @@
     load_observer.Wait();
   }
   scoped_refptr<content::SiteInstance> fourth_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_EQ(fourth_instance, third_instance);
 }
 
@@ -5962,7 +5979,7 @@
       GetGuestViewManager()->WaitForSingleGuestCreated();
   ASSERT_TRUE(guest);
   scoped_refptr<content::SiteInstance> site_instance =
-      guest->GetMainFrame()->GetSiteInstance();
+      guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(site_instance->IsGuest());
   EXPECT_TRUE(site_instance->GetProcess()->IsForGuestsOnly());
 }
@@ -5980,7 +5997,7 @@
       extensions::WebViewRendererState::GetInstance();
 
   // Ensure the <webview>'s SiteInstance is for a guest.
-  content::RenderFrameHost* main_frame = guest->GetMainFrame();
+  content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
   scoped_refptr<content::SiteInstance> starting_instance =
       main_frame->GetSiteInstance();
   EXPECT_TRUE(starting_instance->IsGuest());
@@ -6026,7 +6043,7 @@
 
     // Ensure the new content script is now tracked for the <webview> in the
     // browser process.
-    main_frame = guest->GetMainFrame();
+    main_frame = guest->GetPrimaryMainFrame();
     {
       extensions::WebViewRendererState::WebViewInfo info;
       ASSERT_TRUE(
@@ -6049,7 +6066,7 @@
   EXPECT_TRUE(script_listener.WaitUntilSatisfied());
 
   // Check that the content script is tracked for the new <webview> process.
-  main_frame = guest->GetMainFrame();
+  main_frame = guest->GetPrimaryMainFrame();
   EXPECT_TRUE(main_frame->GetSiteInstance()->IsGuest());
   EXPECT_NE(main_frame->GetSiteInstance(), starting_instance);
   {
@@ -6080,7 +6097,7 @@
   ASSERT_TRUE(guest);
   auto* web_view_renderer_state =
       extensions::WebViewRendererState::GetInstance();
-  content::RenderFrameHost* main_frame = guest->GetMainFrame();
+  content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
 
   // WebViewRendererState should have an entry for a single guest instance.
   ASSERT_EQ(1u, web_view_renderer_state->guest_count_for_testing());
@@ -6117,7 +6134,7 @@
     ASSERT_EQ(2u, web_view_renderer_state->guest_count_for_testing());
   }
 
-  main_frame = guest->GetMainFrame();
+  main_frame = guest->GetPrimaryMainFrame();
   content::RenderFrameHost* subframe = content::ChildFrameAt(main_frame, 0);
 
   // Navigate <webview> subframe cross-site to a URL that matches the content
@@ -6158,7 +6175,7 @@
       embedded_test_server()->GetURL("b.test", "/title1.html");
   EXPECT_TRUE(NavigateIframeToURL(guest, "test", frame_url));
   content::RenderFrameHost* subframe =
-      content::ChildFrameAt(guest->GetMainFrame(), 0);
+      content::ChildFrameAt(guest->GetPrimaryMainFrame(), 0);
 
   // Attach a second <webview>.
   ASSERT_TRUE(content::ExecuteScript(
@@ -6177,12 +6194,13 @@
   const GURL second_guest_url =
       embedded_test_server()->GetURL("c.test", "/iframe.html");
   EXPECT_TRUE(NavigateToURL(guest2, second_guest_url));
-  EXPECT_NE(guest->GetMainFrame()->GetSiteInstance(),
-            guest2->GetMainFrame()->GetSiteInstance());
-  EXPECT_NE(guest->GetMainFrame()->GetProcess(),
-            guest2->GetMainFrame()->GetProcess());
-  EXPECT_FALSE(guest->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-      guest2->GetMainFrame()->GetSiteInstance()));
+  EXPECT_NE(guest->GetPrimaryMainFrame()->GetSiteInstance(),
+            guest2->GetPrimaryMainFrame()->GetSiteInstance());
+  EXPECT_NE(guest->GetPrimaryMainFrame()->GetProcess(),
+            guest2->GetPrimaryMainFrame()->GetProcess());
+  EXPECT_FALSE(
+      guest->GetPrimaryMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
+          guest2->GetPrimaryMainFrame()->GetSiteInstance()));
 
   // Navigate second <webview> subframe to the same site as the first <webview>
   // subframe, ending up with A(B) in `guest` and C(B) in `guest2`.  These
@@ -6191,7 +6209,7 @@
   // reuse policy, they should share the same process.
   EXPECT_TRUE(NavigateIframeToURL(guest2, "test", frame_url));
   content::RenderFrameHost* subframe2 =
-      content::ChildFrameAt(guest2->GetMainFrame(), 0);
+      content::ChildFrameAt(guest2->GetPrimaryMainFrame(), 0);
   EXPECT_NE(subframe->GetSiteInstance(), subframe2->GetSiteInstance());
   EXPECT_EQ(subframe->GetSiteInstance()->GetStoragePartitionConfig(),
             subframe2->GetSiteInstance()->GetStoragePartitionConfig());
@@ -6221,16 +6239,17 @@
 
   auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
   std::vector<content::RenderFrameHost*> rfhs =
-      content::CollectAllRenderFrameHosts(guest_web_contents->GetMainFrame());
+      content::CollectAllRenderFrameHosts(
+          guest_web_contents->GetPrimaryMainFrame());
   ASSERT_EQ(rfhs.size(), 2u);
-  ASSERT_EQ(rfhs[0], guest_web_contents->GetMainFrame());
+  ASSERT_EQ(rfhs[0], guest_web_contents->GetPrimaryMainFrame());
   content::RenderFrameHostWrapper fenced_frame(rfhs[1]);
 
   content::SiteInstance* fenced_frame_site_instance =
       fenced_frame->GetSiteInstance();
   EXPECT_TRUE(fenced_frame_site_instance->IsGuest());
   EXPECT_EQ(fenced_frame_site_instance->GetStoragePartitionConfig(),
-            guest_web_contents->GetMainFrame()
+            guest_web_contents->GetPrimaryMainFrame()
                 ->GetSiteInstance()
                 ->GetStoragePartitionConfig());
 }
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
index 9e44fe9..a0124f8 100644
--- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -324,7 +324,7 @@
     content::Source<content::NavigationController> source =
         guest_observer.source();
     EXPECT_TRUE(source->DeprecatedGetWebContents()
-                    ->GetMainFrame()
+                    ->GetPrimaryMainFrame()
                     ->GetProcess()
                     ->IsForGuestsOnly());
 
@@ -449,8 +449,9 @@
         popup_observer.last_render_widget_host();
     gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds();
 
-    content::RenderViewHost* embedder_rvh =
-        GetFirstAppWindowWebContents()->GetMainFrame()->GetRenderViewHost();
+    content::RenderViewHost* embedder_rvh = GetFirstAppWindowWebContents()
+                                                ->GetPrimaryMainFrame()
+                                                ->GetRenderViewHost();
     gfx::Rect embedder_bounds =
         embedder_rvh->GetWidget()->GetView()->GetViewBounds();
     gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin();
@@ -727,7 +728,7 @@
                   "window.runCommand('testFocusTracksEmbedderRunNextStep');"));
 
   // Blur the embedder.
-  embedder_web_contents->GetMainFrame()
+  embedder_web_contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->Blur();
@@ -754,7 +755,7 @@
         GetGuestViewManager()->WaitForSingleGuestCreated();
 
     SimulateRWHMouseClick(
-        guest->GetMainFrame()->GetRenderViewHost()->GetWidget(),
+        guest->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget(),
         blink::WebMouseEvent::Button::kLeft, 200, 20);
     content::SimulateKeyPress(embedder_web_contents, ui::DomKey::TAB,
                               ui::DomCode::TAB, ui::VKEY_TAB, false, false,
@@ -792,9 +793,13 @@
       GetGuestViewManager()->WaitForSingleGuestCreated();
 
   content::MainThreadFrameObserver embedder_observer(
-      embedder_web_contents->GetMainFrame()->GetView()->GetRenderWidgetHost());
+      embedder_web_contents->GetPrimaryMainFrame()
+          ->GetView()
+          ->GetRenderWidgetHost());
   content::MainThreadFrameObserver guest_observer(
-      guest_web_contents->GetMainFrame()->GetView()->GetRenderWidgetHost());
+      guest_web_contents->GetPrimaryMainFrame()
+          ->GetView()
+          ->GetRenderWidgetHost());
 
   // Embedder should be focused initially.
   EXPECT_EQ(content::GetFocusedWebContents(guest_web_contents),
@@ -1098,11 +1103,12 @@
 
   // |text_input_client| is not available for mac and android.
 #if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
-  ui::TextInputClient* text_input_client = embedder_web_contents->GetMainFrame()
-                                               ->GetRenderViewHost()
-                                               ->GetWidget()
-                                               ->GetView()
-                                               ->GetTextInputClient();
+  ui::TextInputClient* text_input_client =
+      embedder_web_contents->GetPrimaryMainFrame()
+          ->GetRenderViewHost()
+          ->GetWidget()
+          ->GetView()
+          ->GetTextInputClient();
   ASSERT_TRUE(text_input_client);
   ASSERT_TRUE(text_input_client->GetTextInputType() !=
               ui::TEXT_INPUT_TYPE_NONE);
@@ -1123,11 +1129,12 @@
                    &embedder_web_contents));
   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
 
-  ui::TextInputClient* text_input_client = embedder_web_contents->GetMainFrame()
-                                               ->GetRenderViewHost()
-                                               ->GetWidget()
-                                               ->GetView()
-                                               ->GetTextInputClient();
+  ui::TextInputClient* text_input_client =
+      embedder_web_contents->GetPrimaryMainFrame()
+          ->GetRenderViewHost()
+          ->GetWidget()
+          ->GetView()
+          ->GetTextInputClient();
   ASSERT_TRUE(text_input_client);
 
   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED");
@@ -1284,7 +1291,7 @@
   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
 
   content::TextInputTestLocalFrame text_input_local_frame;
-  text_input_local_frame.SetUp(guest_web_contents()->GetMainFrame());
+  text_input_local_frame.SetUp(guest_web_contents()->GetPrimaryMainFrame());
 
   // Lookup some string through context menu.
   ContextMenuNotificationObserver menu_observer(IDC_CONTENT_CONTEXT_LOOK_UP);
@@ -1380,7 +1387,7 @@
   TestHelper("testKeyboardFocusSimple", "web_view/focus", NO_TEST_SERVER);
 
   EXPECT_EQ(embedder_web_contents()->GetFocusedFrame(),
-            embedder_web_contents()->GetMainFrame());
+            embedder_web_contents()->GetPrimaryMainFrame());
   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED");
   next_step_listener.set_failure_message("TEST_STEP_FAILED");
   {
@@ -1427,7 +1434,7 @@
              NO_TEST_SERVER);
 
   EXPECT_EQ(embedder_web_contents()->GetFocusedFrame(),
-            embedder_web_contents()->GetMainFrame());
+            embedder_web_contents()->GetPrimaryMainFrame());
   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED");
   next_step_listener.set_failure_message("TEST_STEP_FAILED");
   {
diff --git a/chrome/browser/apps/platform_apps/app_browsertest.cc b/chrome/browser/apps/platform_apps/app_browsertest.cc
index aa31289..eefcb846 100644
--- a/chrome/browser/apps/platform_apps/app_browsertest.cc
+++ b/chrome/browser/apps/platform_apps/app_browsertest.cc
@@ -335,7 +335,7 @@
   ASSERT_TRUE(web_contents);
   content::ContextMenuParams params;
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
   ASSERT_TRUE(
@@ -354,7 +354,7 @@
   ASSERT_TRUE(web_contents);
   content::ContextMenuParams params;
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   int first_extensions_command_id =
       ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
@@ -383,7 +383,7 @@
   ASSERT_TRUE(web_contents);
   content::ContextMenuParams params;
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   int extensions_custom_id =
       ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
@@ -415,7 +415,7 @@
   content::ContextMenuParams params;
   params.is_editable = true;
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   int extensions_custom_id =
       ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
@@ -440,7 +440,7 @@
   content::ContextMenuParams params;
   params.selection_text = u"Hello World";
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   int extensions_custom_id =
       ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
@@ -464,7 +464,7 @@
   content::ContextMenuParams params;
   params.page_url = GURL("http://foo.bar");
   auto menu = std::make_unique<PlatformAppContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   int extensions_custom_id =
       ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
diff --git a/chrome/browser/apps/platform_apps/app_browsertest_util.cc b/chrome/browser/apps/platform_apps/app_browsertest_util.cc
index 0c52632..f78d854 100644
--- a/chrome/browser/apps/platform_apps/app_browsertest_util.cc
+++ b/chrome/browser/apps/platform_apps/app_browsertest_util.cc
@@ -250,7 +250,7 @@
   ExtensionHost* background_host =
       process_manager->GetBackgroundHostForExtension(extension->id());
   window->Init(GURL(std::string()), new AppWindowContentsImpl(window),
-               background_host->host_contents()->GetMainFrame(), params);
+               background_host->host_contents()->GetPrimaryMainFrame(), params);
   return window;
 }
 
diff --git a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
index 94c3494..79e7e703 100644
--- a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
+++ b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
@@ -352,7 +352,7 @@
       app_window_contents->GetWebContents());
 
   content::RenderFrameHost* main_frame =
-      app_window_contents->GetWebContents()->GetMainFrame();
+      app_window_contents->GetWebContents()->GetPrimaryMainFrame();
   DCHECK(main_frame);
 
   extensions::AppWindow::CreateParams params;
diff --git a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
index e2034c1..4ab3e3b 100644
--- a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
@@ -411,7 +411,8 @@
 void SelectFileDialogHolder::ExecuteJavaScript(
     const std::string& script,
     content::RenderFrameHost::JavaScriptResultCallback callback) {
-  content::RenderFrameHost* frame_host = select_file_dialog_->GetMainFrame();
+  content::RenderFrameHost* frame_host =
+      select_file_dialog_->GetPrimaryMainFrame();
 
   if (!frame_host || !frame_host->IsRenderFrameLive()) {
     LOG(ERROR) << "Can't execute a script. SelectFileDialog is not ready.";
diff --git a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc
index 1d44bf5..e67d86b 100644
--- a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc
+++ b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc
@@ -196,7 +196,7 @@
     return false;
   }
 
-  GURL url = contents_to_use->GetMainFrame()->GetLastCommittedURL();
+  GURL url = contents_to_use->GetPrimaryMainFrame()->GetLastCommittedURL();
   if (!url.SchemeIs("chrome-extension")) {
     VLOG(1) << "Plugin frame URL not loaded yet.";
     return false;
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc
index 652f81a3..1574047 100644
--- a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc
@@ -145,7 +145,7 @@
 
   bool value = false;
   content::ToRenderFrameHost target =
-      content::ToRenderFrameHost(tab->GetMainFrame());
+      content::ToRenderFrameHost(tab->GetPrimaryMainFrame());
   EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
       target, command, &value));
   return value;
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index 8aad7da7b..f14899a5 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -2408,21 +2408,23 @@
   if (name == "executeScriptInChromeUntrusted") {
     for (auto* web_contents : GetAllWebContents()) {
       bool found = false;
-      web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-          [](const base::DictionaryValue& value, bool& found,
-             std::string* output, content::RenderFrameHost* frame) {
-            const url::Origin origin = frame->GetLastCommittedOrigin();
-            if (origin.GetURL() ==
-                ash::file_manager::kChromeUIFileManagerUntrustedURL) {
-              const std::string* script = value.FindStringKey("data");
-              EXPECT_TRUE(script);
-              CHECK(ExecuteScriptAndExtractString(frame, *script, output));
-              found = true;
-              return content::RenderFrameHost::FrameIterationAction::kStop;
-            }
-            return content::RenderFrameHost::FrameIterationAction::kContinue;
-          },
-          std::ref(value), std::ref(found), output));
+      web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+          base::BindRepeating(
+              [](const base::DictionaryValue& value, bool& found,
+                 std::string* output, content::RenderFrameHost* frame) {
+                const url::Origin origin = frame->GetLastCommittedOrigin();
+                if (origin.GetURL() ==
+                    ash::file_manager::kChromeUIFileManagerUntrustedURL) {
+                  const std::string* script = value.FindStringKey("data");
+                  EXPECT_TRUE(script);
+                  CHECK(ExecuteScriptAndExtractString(frame, *script, output));
+                  found = true;
+                  return content::RenderFrameHost::FrameIterationAction::kStop;
+                }
+                return content::RenderFrameHost::FrameIterationAction::
+                    kContinue;
+              },
+              std::ref(value), std::ref(found), output));
       if (found)
         return;
     }
@@ -2953,8 +2955,8 @@
       if (!window->web_contents())
         break;
 
-      CHECK(window->web_contents()->GetMainFrame());
-      window->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+      CHECK(window->web_contents()->GetPrimaryMainFrame());
+      window->web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
           base::UTF8ToUTF16(*script), base::NullCallback());
 
       break;
@@ -3276,7 +3278,7 @@
         content::WebContents::FromRenderViewHost(rvh);
     if (!web_contents)
       continue;
-    if (web_contents->GetMainFrame()->GetRenderViewHost() != rvh)
+    if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost() != rvh)
       continue;
     // Because a WebContents can only have one current RVH at a time, there will
     // be no duplicate WebContents here.
diff --git a/chrome/browser/ash/lock_screen_apps/state_controller_unittest.cc b/chrome/browser/ash/lock_screen_apps/state_controller_unittest.cc
index 3d5e1c33..4084a86d 100644
--- a/chrome/browser/ash/lock_screen_apps/state_controller_unittest.cc
+++ b/chrome/browser/ash/lock_screen_apps/state_controller_unittest.cc
@@ -346,7 +346,7 @@
     extensions::AppWindow::CreateParams params;
     params.hidden = !shown;
     window_->Init(GURL(), new extensions::AppWindowContentsImpl(window_),
-                  web_contents_->GetMainFrame(), params);
+                  web_contents_->GetPrimaryMainFrame(), params);
     Observe(window_->web_contents());
   }
 
diff --git a/chrome/browser/ash/login/lock/screen_locker_browsertest.cc b/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
index b547fc6..108e67a 100644
--- a/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
+++ b/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
@@ -157,7 +157,7 @@
     browser()
         ->exclusive_access_manager()
         ->fullscreen_controller()
-        ->EnterFullscreenModeForTab(web_contents->GetMainFrame());
+        ->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame());
     fullscreen_waiter.Wait();
     EXPECT_TRUE(browser_window->IsFullscreen());
     EXPECT_TRUE(window_state->GetHideShelfWhenFullscreen());
diff --git a/chrome/browser/ash/login/saml/saml_browsertest.cc b/chrome/browser/ash/login/saml/saml_browsertest.cc
index e11187a..a461b0d 100644
--- a/chrome/browser/ash/login/saml/saml_browsertest.cc
+++ b/chrome/browser/ash/login/saml/saml_browsertest.cc
@@ -1677,20 +1677,20 @@
 
   // Mic should always be blocked.
   EXPECT_FALSE(web_contents_delegate->CheckMediaAccessPermission(
-      web_contents->GetMainFrame(), url1,
+      web_contents->GetPrimaryMainFrame(), url1,
       blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE));
 
   // Camera should be allowed if allowed by the allowlist, otherwise blocked.
   EXPECT_TRUE(web_contents_delegate->CheckMediaAccessPermission(
-      web_contents->GetMainFrame(), url1,
+      web_contents->GetPrimaryMainFrame(), url1,
       blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE));
 
   EXPECT_TRUE(web_contents_delegate->CheckMediaAccessPermission(
-      web_contents->GetMainFrame(), url2,
+      web_contents->GetPrimaryMainFrame(), url2,
       blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE));
 
   EXPECT_FALSE(web_contents_delegate->CheckMediaAccessPermission(
-      web_contents->GetMainFrame(), url3,
+      web_contents->GetPrimaryMainFrame(), url3,
       blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE));
 
   // Camera should be blocked in the login screen, even if it's allowed via
@@ -1703,7 +1703,7 @@
                                       CONTENT_SETTING_ALLOW);
 
   EXPECT_FALSE(web_contents_delegate->CheckMediaAccessPermission(
-      web_contents->GetMainFrame(), url3,
+      web_contents->GetPrimaryMainFrame(), url3,
       blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE));
 }
 
diff --git a/chrome/browser/ash/login/screens/hid_detection_screen.cc b/chrome/browser/ash/login/screens/hid_detection_screen.cc
index cbadf50..dbaef3c 100644
--- a/chrome/browser/ash/login/screens/hid_detection_screen.cc
+++ b/chrome/browser/ash/login/screens/hid_detection_screen.cc
@@ -485,14 +485,9 @@
 }
 
 void HIDDetectionScreen::InputDeviceRemoved(const std::string& id) {
-  if (is_hidden()) {
-    devices_.erase(id);
-    return;
-  }
-
-  DCHECK(devices_[id]);
-  hid_detection::RecordHidDisconnected(*devices_[id]);
   devices_.erase(id);
+  if (is_hidden())
+    return;
 
   if (id == touchscreen_id_) {
     touchscreen_id_.clear();
diff --git a/chrome/browser/ash/login/screens/hid_detection_screen_browsertest.cc b/chrome/browser/ash/login/screens/hid_detection_screen_browsertest.cc
index 1e267b19..b3db999 100644
--- a/chrome/browser/ash/login/screens/hid_detection_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/hid_detection_screen_browsertest.cc
@@ -97,11 +97,6 @@
                                         hid_type, count);
   }
 
-  void AssertHidDisconnectedCount(HidType hid_type, int count) {
-    histogram_tester_.ExpectBucketCount(
-        "OOBE.HidDetectionScreen.HidDisconnected", hid_type, count);
-  }
-
   test::HIDControllerMixin hid_controller_{&mixin_host_};
 
  private:
@@ -143,8 +138,6 @@
   // Remove generic devices, add usb devices.
   hid_controller_.RemoveDevices();
   test::OobeJS().ExpectDisabledPath(kHidContinueButton);
-  AssertHidDisconnectedCount(HidType::kSerialKeyboard, /*count=*/1);
-  AssertHidDisconnectedCount(HidType::kSerialPointer, /*count=*/1);
 
   hid_controller_.ConnectUSBDevices();
   // TODO(crbug/1173782): use screen or JS state instead of handler()
@@ -157,8 +150,6 @@
   // Remove usb devices, add bluetooth devices.
   hid_controller_.RemoveDevices();
   test::OobeJS().ExpectDisabledPath(kHidContinueButton);
-  AssertHidDisconnectedCount(HidType::kUsbKeyboard, /*count=*/1);
-  AssertHidDisconnectedCount(HidType::kUsbPointer, /*count=*/1);
 
   hid_controller_.ConnectBTDevices();
   EXPECT_EQ("paired", handler()->mouse_state_for_test());
@@ -166,53 +157,6 @@
   test::OobeJS().ExpectEnabledPath(kHidContinueButton);
   AssertHidConnectedCount(HidType::kBluetoothKeyboard, /*count=*/1);
   AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1);
-
-  // Remove bluetooth devices.
-  hid_controller_.RemoveDevices();
-  AssertHidDisconnectedCount(HidType::kBluetoothKeyboard, /*count=*/1);
-  AssertHidDisconnectedCount(HidType::kBluetoothPointer, /*count=*/1);
-};
-
-IN_PROC_BROWSER_TEST_F(HIDDetectionScreenChromeboxTest,
-                       AddRemoveDevicesAfterScreen) {
-  // NOTE: State strings match those in hid_detection_screen.cc.
-  // No devices added yet
-  EXPECT_EQ("searching", handler()->mouse_state_for_test());
-  EXPECT_EQ("searching", handler()->keyboard_state_for_test());
-  test::OobeJS().ExpectDisabledPath(kHidContinueButton);
-
-  // Generic connection types. Unlike the pointing device, which may be a tablet
-  // or touchscreen, the keyboard only reports usb and bluetooth states.
-  hid_controller_.AddMouse(device::mojom::InputDeviceType::TYPE_SERIO);
-  test::OobeJS().ExpectEnabledPath(kHidContinueButton);
-  AssertHidConnectedCount(HidType::kSerialPointer, /*count=*/1);
-
-  hid_controller_.AddKeyboard(device::mojom::InputDeviceType::TYPE_SERIO);
-  EXPECT_EQ("connected", handler()->mouse_state_for_test());
-  EXPECT_EQ("usb", handler()->keyboard_state_for_test());
-  test::OobeJS().ExpectEnabledPath(kHidContinueButton);
-  AssertHidConnectedCount(HidType::kSerialKeyboard, /*count=*/1);
-
-  ContinueToWelcomeScreen();
-
-  hid_controller_.RemoveDevices();
-
-  AssertHidDisconnectedCount(HidType::kSerialKeyboard, /*count=*/0);
-  AssertHidDisconnectedCount(HidType::kSerialPointer, /*count=*/0);
-
-  // Re-add the generic keyboard/mouse and make sure the count doesn't increase.
-  hid_controller_.AddKeyboard(device::mojom::InputDeviceType::TYPE_SERIO);
-  hid_controller_.AddMouse(device::mojom::InputDeviceType::TYPE_SERIO);
-
-  AssertHidConnectedCount(HidType::kSerialPointer, /*count=*/1);
-  AssertHidConnectedCount(HidType::kSerialKeyboard, /*count=*/1);
-
-  hid_controller_.RemoveDevices();
-
-  // Make sure a not yet added device type also doesn't increment the count.
-  hid_controller_.ConnectUSBDevices();
-  AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/0);
-  AssertHidConnectedCount(HidType::kUsbPointer, /*count=*/0);
 }
 
 // Test that if there is any Bluetooth device connected on HID screen, the
diff --git a/chrome/browser/ash/login/test/js_checker.cc b/chrome/browser/ash/login/test/js_checker.cc
index fdf7b1e..9ff923cf 100644
--- a/chrome/browser/ash/login/test/js_checker.cc
+++ b/chrome/browser/ash/login/test/js_checker.cc
@@ -96,8 +96,9 @@
 void JSChecker::ExecuteAsync(const std::string& expression) {
   CHECK(web_contents_);
   std::string new_script = expression + ";";
-  web_contents_->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
-      base::UTF8ToUTF16(new_script), base::NullCallback());
+  web_contents_->GetPrimaryMainFrame()
+      ->ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(new_script),
+                                                 base::NullCallback());
 }
 
 bool JSChecker::GetBool(const std::string& expression) {
diff --git a/chrome/browser/ash/login/webview_login_browsertest.cc b/chrome/browser/ash/login/webview_login_browsertest.cc
index 8785779..5ddb383 100644
--- a/chrome/browser/ash/login/webview_login_browsertest.cc
+++ b/chrome/browser/ash/login/webview_login_browsertest.cc
@@ -950,7 +950,7 @@
   content::WebContents* web_contents = GetLoginUI()->GetWebContents();
   bool getUserMediaSuccess = false;
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       "navigator.getUserMedia("
       "    {video: true},"
       "    function() { window.domAutomationController.send(true); },"
@@ -960,7 +960,7 @@
 
   // Audio devices should be denied from the login screen.
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       "navigator.getUserMedia("
       "    {audio: true},"
       "    function() { window.domAutomationController.send(true); },"
diff --git a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.cc b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.cc
index f449a40..84d4b897 100644
--- a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.cc
+++ b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.cc
@@ -51,8 +51,14 @@
          item_metadata.file_size_bytes();
 }
 
-secure_channel::mojom::PayloadFilesPtr DoCreatePayloadFiles(
+absl::optional<secure_channel::mojom::PayloadFilesPtr> DoCreatePayloadFiles(
     const base::FilePath& file_path) {
+  if (base::PathExists(file_path)) {
+    // Perhaps a file was created at the same path for a different payload after
+    // we checkedfor its existence.
+    return absl::nullopt;
+  }
+
   base::File output_file =
       base::File(file_path, base::File::Flags::FLAG_CREATE_ALWAYS |
                                 base::File::Flags::FLAG_WRITE);
@@ -152,12 +158,29 @@
     const base::FilePath& file_path,
     int64_t file_size_bytes,
     CreatePayloadFilesCallback payload_files_callback,
-    secure_channel::mojom::PayloadFilesPtr payload_files) {
+    absl::optional<secure_channel::mojom::PayloadFilesPtr> payload_files) {
+  if (!payload_files) {
+    PA_LOG(WARNING) << "Failed to create files for payload " << payload_id
+                    << ": the requested file path already exists.";
+    return std::move(payload_files_callback)
+        .Run(CreatePayloadFilesResult::kNotUniqueFilePath, absl::nullopt);
+  }
+
   const std::string& holding_space_item_id =
       holding_space_keyed_service_->AddPhoneHubCameraRollItem(
           file_path,
           ash::HoldingSpaceProgress(/*current_bytes=*/0,
                                     /*total_bytes=*/file_size_bytes));
+  if (holding_space_item_id.empty()) {
+    // This can happen if a file was created at the same path for a previous
+    // payload but then got deleted before that payload is fully downloaded.
+    PA_LOG(WARNING) << "Failed to add payload " << payload_id
+                    << " to holding space. It's likely that an item with the "
+                       "same file path already exists.";
+    return std::move(payload_files_callback)
+        .Run(CreatePayloadFilesResult::kNotUniqueFilePath, absl::nullopt);
+  }
+
   pending_downloads_.emplace(
       payload_id, DownloadItem(payload_id, file_path, file_size_bytes,
                                holding_space_item_id));
@@ -176,23 +199,29 @@
   }
 
   const DownloadItem& download_item = it->second;
-  const bool is_complete =
-      update->status == secure_channel::mojom::FileTransferStatus::kSuccess;
-  holding_space_keyed_service_->UpdateItem(download_item.holding_space_item_id)
-      ->SetProgress(ash::HoldingSpaceProgress(update->bytes_transferred,
-                                              update->total_bytes, is_complete))
-      .SetInvalidateImage(is_complete);
+  const std::string holding_space_item_id = download_item.holding_space_item_id;
 
   switch (update->status) {
     case secure_channel::mojom::FileTransferStatus::kInProgress:
+      holding_space_keyed_service_->UpdateItem(holding_space_item_id)
+          ->SetProgress(ash::HoldingSpaceProgress(update->bytes_transferred,
+                                                  update->total_bytes,
+                                                  /*complete=*/false));
       return;
     case secure_channel::mojom::FileTransferStatus::kFailure:
     case secure_channel::mojom::FileTransferStatus::kCanceled:
       // Delete files created for failed and canceled items, in addition to
       // removing the DownloadItem objects.
+      holding_space_keyed_service_->RemoveItem(holding_space_item_id);
       DeleteFile(update->payload_id);
       return;
     case secure_channel::mojom::FileTransferStatus::kSuccess:
+      holding_space_keyed_service_
+          ->UpdateItem(download_item.holding_space_item_id)
+          ->SetProgress(ash::HoldingSpaceProgress(update->bytes_transferred,
+                                                  update->total_bytes,
+                                                  /*complete=*/true))
+          .SetInvalidateImage(true);
       base::UmaHistogramCounts100000(
           "PhoneHub.CameraRoll.DownloadItem.TransferRate",
           CalculateItemTransferRate(download_item));
diff --git a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.h b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.h
index f7d082e..790b7e15 100644
--- a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.h
+++ b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl.h
@@ -73,7 +73,7 @@
       const base::FilePath& file_path,
       int64_t file_size_bytes,
       CreatePayloadFilesCallback payload_files_callback,
-      secure_channel::mojom::PayloadFilesPtr payload_files);
+      absl::optional<secure_channel::mojom::PayloadFilesPtr> payload_files);
   int CalculateItemTransferRate(const DownloadItem& download_item) const;
 
   const base::FilePath download_path_;
diff --git a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl_unittest.cc b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl_unittest.cc
index b2050f0a..404e7c4 100644
--- a/chrome/browser/ash/phonehub/camera_roll_download_manager_impl_unittest.cc
+++ b/chrome/browser/ash/phonehub/camera_roll_download_manager_impl_unittest.cc
@@ -237,6 +237,28 @@
       GetDownloadPath().Append("IMG_0001 (1).jpeg")));
 }
 
+TEST_F(CameraRollDownloadManagerImplTest,
+       CreatePayloadFilesWithFilePathCollision) {
+  proto::CameraRollItemMetadata item_metadata;
+  item_metadata.set_file_name("IMG_0001.jpeg");
+  item_metadata.set_file_size_bytes(1000);
+
+  // Delete the file for this payload after it has been added to holding space.
+  // If CreatePayloadFiles is called for the same item again, it will create the
+  // file at the same path. However adding the new payload to holding space will
+  // fail because the first payload already exists in the model with the same
+  // path.
+  CreatePayloadFiles(/*payload_id=*/1234, item_metadata);
+  base::FilePath file_path = GetDownloadPath().Append("IMG_0001.jpeg");
+  EXPECT_TRUE(GetHoldingSpaceModel()->ContainsItem(
+      HoldingSpaceItem::Type::kPhoneHubCameraRoll, file_path));
+  EXPECT_TRUE(base::DeleteFile(file_path));
+
+  CreatePayloadFilesResult error =
+      CreatePayloadFilesAndGetError(/*payload_id=*/-5678, item_metadata);
+  EXPECT_EQ(CreatePayloadFilesResult::kNotUniqueFilePath, error);
+}
+
 TEST_F(CameraRollDownloadManagerImplTest, UpdateDownloadProgress) {
   proto::CameraRollItemMetadata item_metadata;
   item_metadata.set_file_name("IMG_0001.jpeg");
@@ -357,7 +379,6 @@
   CreatePayloadFiles(/*payload_id=*/1234, item_metadata);
 
   base::FilePath expected_path = GetDownloadPath().Append("IMG_0001.jpeg");
-  EXPECT_TRUE(base::PathExists(expected_path));
   base::RunLoop delete_file_run_loop;
   base::FilePathWatcher watcher;
   watcher.Watch(expected_path, base::FilePathWatcher::Type::kNonRecursive,
@@ -365,6 +386,16 @@
                     [&](const base::FilePath& file_path, bool error) {
                       delete_file_run_loop.Quit();
                     }));
+  camera_roll_download_manager()->UpdateDownloadProgress(
+      secure_channel::mojom::FileTransferUpdate::New(
+          /*payload_id=*/1234,
+          secure_channel::mojom::FileTransferStatus::kInProgress,
+          /*total_bytes=*/1000,
+          /*bytes_transferred=*/200));
+
+  EXPECT_TRUE(GetHoldingSpaceModel()->ContainsItem(
+      HoldingSpaceItem::Type::kPhoneHubCameraRoll, expected_path));
+  EXPECT_TRUE(base::PathExists(expected_path));
 
   camera_roll_download_manager()->UpdateDownloadProgress(
       secure_channel::mojom::FileTransferUpdate::New(
@@ -374,6 +405,8 @@
           /*bytes_transferred=*/200));
   delete_file_run_loop.Run();
 
+  EXPECT_FALSE(GetHoldingSpaceModel()->ContainsItem(
+      HoldingSpaceItem::Type::kPhoneHubCameraRoll, expected_path));
   EXPECT_FALSE(base::PathExists(expected_path));
 }
 
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_browsertest.cc b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_browsertest.cc
index bbb43eb..36f7799 100644
--- a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_browsertest.cc
@@ -102,9 +102,10 @@
     std::string requested_video_device_id,
     blink::mojom::MediaStreamType video_type) {
   return content::MediaStreamRequest(
-      web_contents->GetMainFrame()->GetProcess()->GetID(),
-      web_contents->GetMainFrame()->GetRoutingID(), /*page_request_id=*/0,
-      GURL(kExampleUrl), /*user_gesture=*/false, blink::MEDIA_GENERATE_STREAM,
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents->GetPrimaryMainFrame()->GetRoutingID(),
+      /*page_request_id=*/0, GURL(kExampleUrl), /*user_gesture=*/false,
+      blink::MEDIA_GENERATE_STREAM,
       /*requested_audio_device_id=*/std::string(), requested_video_device_id,
       blink::mojom::MediaStreamType::NO_SERVICE, video_type,
       /*disable_local_echo=*/false,
@@ -794,8 +795,8 @@
                                            content::DesktopMediaID::kFakeId);
     const std::string requested_video_device_id =
         content::DesktopStreamsRegistry::GetInstance()->RegisterStream(
-            web_contents->GetMainFrame()->GetProcess()->GetID(),
-            web_contents->GetMainFrame()->GetRoutingID(),
+            web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+            web_contents->GetPrimaryMainFrame()->GetRoutingID(),
             url::Origin::Create(GURL(kExampleUrl)), media_id,
             /*extension_name=*/"",
             content::DesktopStreamRegistryType::kRegistryStreamTypeDesktop);
@@ -823,8 +824,8 @@
         content::DesktopMediaID::TYPE_WEB_CONTENTS,
         content::DesktopMediaID::kNullId,
         content::WebContentsMediaCaptureId(
-            web_contents->GetMainFrame()->GetProcess()->GetID(),
-            web_contents->GetMainFrame()->GetRoutingID()));
+            web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+            web_contents->GetPrimaryMainFrame()->GetRoutingID()));
     extensions::TabCaptureRegistry::Get(browser()->profile())
         ->AddRequest(web_contents, /*extension_id=*/"", /*is_anonymous=*/false,
                      GURL(kExampleUrl), media_id, /*extension_name=*/"",
@@ -1030,8 +1031,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents->GetMainFrame()->GetProcess()->GetID(),
-          web_contents->GetMainFrame()->GetRoutingID()));
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents->GetPrimaryMainFrame()->GetRoutingID()));
   manager->OnScreenShareStarted(kLabel, {media_id}, kApplicationTitle,
                                 stop_cb_.Get(), state_change_cb_.Get(),
                                 base::DoNothing());
@@ -1063,8 +1064,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          new_web_contents->GetMainFrame()->GetProcess()->GetID(),
-          new_web_contents->GetMainFrame()->GetRoutingID()));
+          new_web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          new_web_contents->GetPrimaryMainFrame()->GetRoutingID()));
   // Simulate changing the source to another tab.
   manager->OnScreenShareSourceChanging(kLabel, media_id, new_media_id);
   EXPECT_FALSE(display_service_tester.GetNotification(
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_unittest.cc
index 33dc63d..0940901 100644
--- a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash_unittest.cc
@@ -1072,8 +1072,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents->GetMainFrame()->GetProcess()->GetID(),
-          web_contents->GetMainFrame()->GetRoutingID()));
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents->GetPrimaryMainFrame()->GetRoutingID()));
   GetManager()->CheckScreenShareRestriction(media_id, kApplicationName,
                                             cb.Get());
   VerifyHistogramCounts(/*blocked_count=*/0, /*warned_count=*/0,
@@ -1128,8 +1128,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents->GetMainFrame()->GetProcess()->GetID(),
-          web_contents->GetMainFrame()->GetRoutingID()));
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents->GetPrimaryMainFrame()->GetRoutingID()));
 
   // Warn restriction is enforced: allow and remember that the user proceeded.
   helper_.ChangeConfidentiality(web_contents.get(), kScreenShareWarned);
@@ -1178,8 +1178,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents->GetMainFrame()->GetProcess()->GetID(),
-          web_contents->GetMainFrame()->GetRoutingID()));
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents->GetPrimaryMainFrame()->GetRoutingID()));
 
   // Warn restriction is enforced: reject since the user canceled.
   helper_.ChangeConfidentiality(web_contents.get(), kScreenShareWarned);
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.cc
index 4b50223..c3de774 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.cc
@@ -74,10 +74,6 @@
 
 }  // namespace
 
-// static
-const base::Feature MetricReportingManager::kEnableNetworkTelemetryReporting{
-    "EnableNetworkTelemetryReporting", base::FEATURE_ENABLED_BY_DEFAULT};
-
 bool MetricReportingManager::Delegate::IsAffiliated(Profile* profile) {
   const user_manager::User* const user =
       ash::ProfileHelper::Get()->GetUserByProfile(profile);
@@ -304,15 +300,13 @@
       ::ash::kReportDeviceBootMode,
       /*default_value=*/true, telemetry_report_queue_.get());
 
-  if (base::FeatureList::IsEnabled(kEnableNetworkTelemetryReporting)) {
-    // Network health info.
-    // ReportDeviceNetworkConfiguration policy is enabled by default, so set its
-    // default value to true.
-    InitOneShotCollector(
-        std::make_unique<NetworkInfoSampler>(), info_report_queue_.get(),
-        /*enable_setting_path=*/::ash::kReportDeviceNetworkConfiguration,
-        /*setting_enabled_default_value=*/true);
-  }
+  // Network health info.
+  // ReportDeviceNetworkConfiguration policy is enabled by default, so set its
+  // default value to true.
+  InitOneShotCollector(
+      std::make_unique<NetworkInfoSampler>(), info_report_queue_.get(),
+      /*enable_setting_path=*/::ash::kReportDeviceNetworkConfiguration,
+      /*setting_enabled_default_value=*/true);
 
   initial_upload_timer_.Start(FROM_HERE, delegate_->GetInitialUploadDelay(),
                               this, &MetricReportingManager::UploadTelemetry);
@@ -326,13 +320,11 @@
       std::make_unique<AudioEventsObserver>(),
       /*enable_setting_path=*/::ash::kReportDeviceAudioStatus,
       kReportDeviceAudioStatusDefaultValue);
-  if (base::FeatureList::IsEnabled(kEnableNetworkTelemetryReporting)) {
-    // Network health events observer.
-    InitEventObserverManager(
-        std::make_unique<NetworkEventsObserver>(),
-        /*enable_setting_path=*/::ash::kReportDeviceNetworkStatus,
-        kReportDeviceNetworkStatusDefaultValue);
-  }
+  // Network health events observer.
+  InitEventObserverManager(
+      std::make_unique<NetworkEventsObserver>(),
+      /*enable_setting_path=*/::ash::kReportDeviceNetworkStatus,
+      kReportDeviceNetworkStatusDefaultValue);
   InitPeripheralsCollectors();
 }
 
@@ -447,9 +439,6 @@
       ::ash::kReportDeviceNetworkTelemetryCollectionRateMs,
       GetDefaulCollectionRate(kDefaultNetworkTelemetryCollectionRate));
 
-  if (!base::FeatureList::IsEnabled(kEnableNetworkTelemetryReporting)) {
-    return;
-  }
   // HttpsLatency events.
   InitPeriodicEventCollector(
       std::move(https_latency_sampler),
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
index 84dd622f..bf134d7 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
@@ -37,8 +37,6 @@
 class MetricReportingManager : public policy::ManagedSessionService::Observer,
                                public ::ash::DeviceSettingsService::Observer {
  public:
-  static const base::Feature kEnableNetworkTelemetryReporting;
-
   // Delegate class for dependencies and behaviors that need to be overridden
   // for testing purposes.
   class Delegate {
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
index c350057..ee61e497 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
@@ -329,20 +329,10 @@
     MetricReportingManagerInfoTests,
     MetricReportingManagerInfoTest,
     ::testing::ValuesIn<MetricReportingManagerTestCase>(
-        {{"NetworkInfo_FeatureDisabled",
+        {{"NetworkInfo",
           /*enabled_features=*/{},
-          /*disabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
-          /*is_affiliated=*/false,
-          network_info_settings,
-          /*expected_count_before_login=*/0,
-          /*expected_count_after_login=*/0},
-         {"NetworkInfo_FeatureEnabled",
-          /*enabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
           /*disabled_features=*/{},
-          /*is_affiliated=*/false,
-          network_info_settings,
+          /*is_affiliated=*/false, network_info_settings,
           /*expected_count_before_login=*/1,
           /*expected_count_after_login=*/1},
          {"CpuInfo",
@@ -414,28 +404,16 @@
     MetricReportingManagerEventTests,
     MetricReportingManagerEventTest,
     ::testing::ValuesIn<MetricReportingManagerTestCase>(
-        {{"NetworkEvent_FeatureDisabled",
+        {{"NetworkEvent_Unaffiliated",
           /*enabled_features=*/{},
-          /*disabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
-          /*is_affiliated=*/true,
-          network_event_settings,
-          /*expected_count_before_login=*/0,
-          /*expected_count_after_login=*/0},
-         {"NetworkEvent_Unaffiliated",
-          /*enabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
           /*disabled_features=*/{},
-          /*is_affiliated=*/false,
-          network_event_settings,
+          /*is_affiliated=*/false, network_event_settings,
           /*expected_count_before_login=*/0,
           /*expected_count_after_login=*/0},
          {"NetworkEvent_Default",
-          /*enabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
+          /*enabled_features=*/{},
           /*disabled_features=*/{},
-          /*is_affiliated=*/true,
-          network_event_settings,
+          /*is_affiliated=*/true, network_event_settings,
           /*expected_count_before_login=*/0,
           /*expected_count_after_login=*/1},
          {"AudioEvent_Unaffiliated",
@@ -702,28 +680,16 @@
     MetricReportingManagerPeriodicEventTests,
     MetricReportingManagerPeriodicEventTest,
     ::testing::ValuesIn<MetricReportingManagerTestCase>(
-        {{"NetworkPeriodicEvent_FeatureDisabled",
+        {{"NetworkPeriodicEvent_Unaffiliated",
           /*enabled_features=*/{},
-          /*disabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
-          /*is_affiliated=*/true,
-          network_event_settings,
-          /*expected_count_before_login=*/0,
-          /*expected_count_after_login=*/0},
-         {"NetworkPeriodicEvent_Unaffiliated",
-          /*enabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
           /*disabled_features=*/{},
-          /*is_affiliated=*/false,
-          network_event_settings,
+          /*is_affiliated=*/false, network_event_settings,
           /*expected_count_before_login=*/0,
           /*expected_count_after_login=*/0},
          {"NetworkPeriodicEvent_Default",
-          /*enabled_features=*/
-          {MetricReportingManager::kEnableNetworkTelemetryReporting},
+          /*enabled_features=*/{},
           /*disabled_features=*/{},
-          /*is_affiliated=*/true,
-          network_event_settings,
+          /*is_affiliated=*/true, network_event_settings,
           /*expected_count_before_login=*/0,
           /*expected_count_after_login=*/1}}),
     [](const testing::TestParamInfo<
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler.cc
index 6a3bcee..a0c7cdda 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler.cc
@@ -129,9 +129,6 @@
 void NetworkTelemetrySampler::HandleNetworkTelemetryResult(
     OptionalMetricCallback callback,
     ::chromeos::cros_healthd::mojom::TelemetryInfoPtr result) {
-  bool full_telemetry_reporting_enabled = base::FeatureList::IsEnabled(
-      MetricReportingManager::kEnableNetworkTelemetryReporting);
-
   if (result.is_null() || result->network_interface_result.is_null()) {
     DVLOG(1) << "cros_healthd: Error getting network result, result is null.";
   } else if (result->network_interface_result->is_error()) {
@@ -165,46 +162,41 @@
       continue;
     }
 
-    bool item_reported = full_telemetry_reporting_enabled;
-    NetworkTelemetry* network_telemetry = nullptr;
-    if (full_telemetry_reporting_enabled) {
-      if (network->IsOnline()) {
-        should_collect_latency = true;
-      }
+    should_report = true;
+    if (network->IsOnline()) {
+      should_collect_latency = true;
+    }
 
-      network_telemetry = metric_data.mutable_telemetry_data()
-                              ->mutable_networks_telemetry()
-                              ->add_network_telemetry();
+    NetworkTelemetry* const network_telemetry =
+        metric_data.mutable_telemetry_data()
+            ->mutable_networks_telemetry()
+            ->add_network_telemetry();
 
-      network_telemetry->set_guid(network->guid());
+    network_telemetry->set_guid(network->guid());
 
-      network_telemetry->set_connection_state(
-          GetNetworkConnectionState(network));
+    network_telemetry->set_type(GetNetworkType(type));
 
-      if (!network->device_path().empty()) {
-        network_telemetry->set_device_path(network->device_path());
-      }
+    network_telemetry->set_connection_state(GetNetworkConnectionState(network));
 
-      if (!network->GetIpAddress().empty()) {
-        network_telemetry->set_ip_address(network->GetIpAddress());
-      }
+    if (!network->device_path().empty()) {
+      network_telemetry->set_device_path(network->device_path());
+    }
 
-      if (!network->GetGateway().empty()) {
-        network_telemetry->set_gateway(network->GetGateway());
-      }
+    if (!network->GetIpAddress().empty()) {
+      network_telemetry->set_ip_address(network->GetIpAddress());
+    }
+
+    if (!network->GetGateway().empty()) {
+      network_telemetry->set_gateway(network->GetGateway());
     }
 
     if (type.Equals(::ash::NetworkTypePattern::WiFi())) {
+      network_telemetry->set_signal_strength(network->signal_strength());
+
       const auto& network_interface_info =
           GetWifiNetworkInterfaceInfo(network->device_path(), result);
       if (!network_interface_info.is_null() &&
           !network_interface_info->get_wireless_interface_info().is_null()) {
-        item_reported = true;
-        if (!network_telemetry) {
-          network_telemetry = metric_data.mutable_telemetry_data()
-                                  ->mutable_networks_telemetry()
-                                  ->add_network_telemetry();
-        }
         const auto& wireless_info =
             network_interface_info->get_wireless_interface_info();
 
@@ -228,14 +220,6 @@
           network_telemetry->set_link_quality(wireless_link_info->link_quality);
         }
       }
-      if (item_reported) {
-        network_telemetry->set_signal_strength(network->signal_strength());
-      }
-    }
-
-    if (item_reported) {
-      network_telemetry->set_type(GetNetworkType(type));
-      should_report = true;
     }
   }
 
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
index 1b1cac4..72be274 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
@@ -114,12 +114,7 @@
 
   void TearDown() override { ash::cros_healthd::FakeCrosHealthd::Shutdown(); }
 
-  void SetNetworkData(const std::vector<FakeNetworkData>& networks_data,
-                      bool enable_full_network_telemetry_reporting = true) {
-    scoped_feature_list_.InitWithFeatureState(
-        MetricReportingManager::kEnableNetworkTelemetryReporting,
-        enable_full_network_telemetry_reporting);
-
+  void SetNetworkData(const std::vector<FakeNetworkData>& networks_data) {
     auto* const service_client = network_handler_test_helper_.service_test();
     auto* const device_client = network_handler_test_helper_.device_test();
     auto* const ip_config_client =
@@ -505,69 +500,6 @@
                    .has_power_management_enabled());
 }
 
-TEST_F(NetworkTelemetrySamplerTest, FullNetworkTelemetryReportingDisabled) {
-  const std::vector<FakeNetworkData> networks_data = {
-      {"guid1", shill::kStateReady, shill::kTypeWifi, 10 /* signal_strength */,
-       "wlan0", "192.168.86.25" /* ip_address */, "192.168.86.1" /* gateway */,
-       false /* is_portal */, true /* is_visible */, true /* is_configured */},
-      {"guid2", shill::kStateOnline, shill::kTypeWifi, kSignalStrength,
-       kInterfaceName, "192.168.86.26" /* ip_address */,
-       "192.168.86.2" /* gateway */, false /* is_portal */,
-       true /* is_visible */, true /* is_configured */},
-      {"guid3", shill::kStateReady, shill::kTypeWifi, 10 /* signal_strength */,
-       "wlan1", "192.168.86.27" /* ip_address */, "192.168.86.3" /* gateway */,
-       false /* is_portal */, true /* is_visible */, true /* is_configured */}};
-
-  SetNetworkData(networks_data,
-                 /*enable_full_network_telemetry_reporting=*/false);
-  NetworkTelemetrySampler network_telemetry_sampler(
-      https_latency_sampler_.get());
-  test::TestEvent<absl::optional<MetricData>> metric_collect_event;
-  network_telemetry_sampler.MaybeCollect(metric_collect_event.cb());
-  const absl::optional<MetricData> optional_result =
-      metric_collect_event.result();
-
-  ASSERT_TRUE(optional_result.has_value());
-  ASSERT_TRUE(optional_result->has_telemetry_data());
-  const TelemetryData& result = optional_result->telemetry_data();
-  ASSERT_TRUE(result.has_networks_telemetry());
-
-  // Flag is disabled, no latency data should be collected
-  EXPECT_FALSE(result.networks_telemetry().has_https_latency_data());
-
-  // Only cros healhd wifi interface data should be collected.
-  ASSERT_THAT(result.networks_telemetry().network_telemetry(),
-              ::testing::SizeIs(1));
-
-  EXPECT_FALSE(result.networks_telemetry().network_telemetry(0).has_guid());
-  EXPECT_FALSE(
-      result.networks_telemetry().network_telemetry(0).has_connection_state());
-  EXPECT_FALSE(
-      result.networks_telemetry().network_telemetry(0).has_device_path());
-  EXPECT_FALSE(
-      result.networks_telemetry().network_telemetry(0).has_ip_address());
-  EXPECT_FALSE(result.networks_telemetry().network_telemetry(0).has_gateway());
-
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).type(),
-            NetworkType::WIFI);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).signal_strength(),
-            kSignalStrength);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).tx_bit_rate_mbps(),
-            kTxBitRateMbps);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).rx_bit_rate_mbps(),
-            kRxBitRateMbps);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).tx_power_dbm(),
-            kTxPowerDbm);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).encryption_on(),
-            kEncryptionOn);
-  EXPECT_EQ(result.networks_telemetry().network_telemetry(0).link_quality(),
-            kLinkQuality);
-  EXPECT_EQ(result.networks_telemetry()
-                .network_telemetry(0)
-                .power_management_enabled(),
-            kPowerManagementOn);
-}
-
 TEST_F(NetworkTelemetrySamplerTest, WifiNotConnected) {
   const std::vector<FakeNetworkData> networks_data = {
       {"guid1", shill::kStateIdle, shill::kTypeWifi, kSignalStrength,
diff --git a/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager.cc b/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager.cc
index 42b5a85..e5f9fd00 100644
--- a/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager.cc
+++ b/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager.cc
@@ -87,7 +87,7 @@
     DCHECK(tab_strip_model);
     content::WebContents* contents = tab_strip_model->GetActiveWebContents();
     if (contents) {
-      tab_id = contents->GetMainFrame()->GetPageUkmSourceId();
+      tab_id = contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
       has_form_entry = FormInteractionTabHelper::FromWebContents(contents)
                            ->had_form_interaction();
     }
diff --git a/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager_unittest.cc b/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager_unittest.cc
index f0447b3f..ccb2638e 100644
--- a/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager_unittest.cc
+++ b/chrome/browser/ash/power/ml/adaptive_screen_brightness_manager_unittest.cc
@@ -219,7 +219,7 @@
       tab_strip_model->ActivateTabAt(tab_strip_model->count() - 1);
     }
     content::WebContentsTester::For(contents)->TestSetIsLoading(false);
-    return contents->GetMainFrame()->GetPageUkmSourceId();
+    return contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   }
 
   const gfx::Point kEventLocation = gfx::Point(90, 90);
diff --git a/chrome/browser/ash/power/ml/user_activity_manager.cc b/chrome/browser/ash/power/ml/user_activity_manager.cc
index 5be6bef..fe26134 100644
--- a/chrome/browser/ash/power/ml/user_activity_manager.cc
+++ b/chrome/browser/ash/power/ml/user_activity_manager.cc
@@ -575,7 +575,8 @@
     content::WebContents* contents = tab_strip_model->GetActiveWebContents();
 
     if (contents) {
-      ukm::SourceId source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+      ukm::SourceId source_id =
+          contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
       if (source_id == ukm::kInvalidSourceId)
         return property;
 
diff --git a/chrome/browser/ash/power/ml/user_activity_manager_unittest.cc b/chrome/browser/ash/power/ml/user_activity_manager_unittest.cc
index fce71be..00b6513 100644
--- a/chrome/browser/ash/power/ml/user_activity_manager_unittest.cc
+++ b/chrome/browser/ash/power/ml/user_activity_manager_unittest.cc
@@ -262,7 +262,7 @@
       WebContentsTester::For(contents)->SetMainFrameMimeType(mime_type);
 
     WebContentsTester::For(contents)->TestSetIsLoading(false);
-    return contents->GetMainFrame()->GetPageUkmSourceId();
+    return contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   }
 
   TestingUserActivityUkmLogger delegate_;
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
index ebd4d55b..0d94398 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
@@ -167,8 +167,8 @@
   WindowPropertyWaiter<bool> window_property_waiter(
       web_contents->GetTopLevelNativeWindow(),
       chromeos::kWindowManagerManagesOpacityKey);
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(javascript,
-                                                          base::DoNothing());
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+      javascript, base::DoNothing());
   window_property_waiter.Wait();
 }
 
@@ -249,8 +249,9 @@
     EXPECT_FALSE(widget->IsFullscreen());
 
     FullscreenNotificationObserver waiter(browser);
-    web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
-        u"personalizationTestApi.enterFullscreen();", base::NullCallback());
+    web_contents->GetPrimaryMainFrame()
+        ->ExecuteJavaScriptWithUserGestureForTests(
+            u"personalizationTestApi.enterFullscreen();", base::NullCallback());
     waiter.Wait();
 
     // After the full screen change is observed, there is a significant delay
@@ -259,7 +260,7 @@
     // allows shelf to hide, app list to hide, and wallpaper to change.
     for (int i = 0; i < 3; i++) {
       base::RunLoop loop;
-      web_contents->GetMainFrame()->InsertVisualStateCallback(
+      web_contents->GetPrimaryMainFrame()->InsertVisualStateCallback(
           base::BindLambdaForTesting([&loop](bool visual_state_updated) {
             ASSERT_TRUE(visual_state_updated);
             loop.Quit();
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
index 8cf3ca2..438eaf63 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -594,13 +594,18 @@
 
 void PersonalizationAppWallpaperProviderImpl::UpdateDailyRefreshWallpaper(
     UpdateDailyRefreshWallpaperCallback callback) {
-  if (pending_update_daily_refresh_wallpaper_callback_)
+  if (pending_update_daily_refresh_wallpaper_callback_) {
     std::move(pending_update_daily_refresh_wallpaper_callback_)
         .Run(/*success=*/false);
+  }
+
   pending_update_daily_refresh_wallpaper_callback_ = std::move(callback);
 
-  WallpaperControllerClientImpl::Get()->RecordWallpaperSourceUMA(
-      ash::WallpaperType::kDaily);
+  auto* client = WallpaperControllerClientImpl::Get();
+  ash::WallpaperInfo info = client->GetActiveUserWallpaperInfo();
+  DCHECK(info.type == WallpaperType::kDaily ||
+         info.type == WallpaperType::kDailyGooglePhotos);
+  client->RecordWallpaperSourceUMA(info.type);
 
   WallpaperController::Get()->UpdateDailyRefreshWallpaper(base::BindOnce(
       &PersonalizationAppWallpaperProviderImpl::OnDailyRefreshWallpaperUpdated,
@@ -848,10 +853,27 @@
     const GURL& wallpaper_data_url,
     mojo::StructPtr<ash::personalization_app::mojom::GooglePhotosPhoto> photo,
     bool success) {
+  // If the fetch for |photo| succeeded but |photo| does not exist, that means
+  // it has been removed from the user's library. When this occurs, the user's
+  // wallpaper should be either (a) reset to default or (b) updated to a new
+  // photo from the same collection depending on whether daily refresh is
+  // enabled.
+  if (success && !photo) {
+    if (info.type == WallpaperType::kOnceGooglePhotos) {
+      SelectDefaultImage(/*callback=*/base::DoNothing());
+    } else if (info.type == WallpaperType::kDailyGooglePhotos) {
+      UpdateDailyRefreshWallpaper(/*callback=*/base::DoNothing());
+    } else {
+      NOTREACHED();
+    }
+    return;
+  }
+
   std::vector<std::string> attribution;
   if (!photo.is_null()) {
     attribution.push_back(photo->name);
   }
+
   // NOTE: Old clients may not support |dedup_key| when setting Google Photos
   // wallpaper, so use |location| in such cases for backwards compatibility.
   NotifyWallpaperChanged(ash::personalization_app::mojom::CurrentWallpaper::New(
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc
index 1c63631..80e8e04 100644
--- a/chrome/browser/autofill/android/personal_data_manager_android.cc
+++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -135,7 +135,7 @@
     }
 
     ContentAutofillDriver* driver =
-        factory->DriverForFrame(contents->GetMainFrame());
+        factory->DriverForFrame(contents->GetPrimaryMainFrame());
     if (!driver) {
       OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE);
       return;
diff --git a/chrome/browser/autofill/autofill_autocomplete_browsertest.cc b/chrome/browser/autofill/autofill_autocomplete_browsertest.cc
index c416dc7..28dc4c4 100644
--- a/chrome/browser/autofill/autofill_autocomplete_browsertest.cc
+++ b/chrome/browser/autofill/autofill_autocomplete_browsertest.cc
@@ -93,7 +93,7 @@
     content::WebContents* web_contents =
         active_browser_->tab_strip_model()->GetActiveWebContents();
     ContentAutofillDriverFactory::FromWebContents(web_contents)
-        ->DriverForFrame(web_contents->GetMainFrame())
+        ->DriverForFrame(web_contents->GetPrimaryMainFrame())
         ->autofill_manager()
         ->client()
         ->HideAutofillPopup(PopupHidingReason::kTabGone);
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index 9891df9..7c66341 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -121,7 +121,7 @@
  public:
   explicit MockAutofillManagerInjector(content::WebContents* web_contents)
       : WebContentsObserver(web_contents) {
-    Inject(web_contents->GetMainFrame());
+    Inject(web_contents->GetPrimaryMainFrame());
   }
   ~MockAutofillManagerInjector() override = default;
 
@@ -172,7 +172,7 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     AutofillManager* autofill_manager =
         ContentAutofillDriverFactory::FromWebContents(web_contents)
-            ->DriverForFrame(web_contents->GetMainFrame())
+            ->DriverForFrame(web_contents->GetPrimaryMainFrame())
             ->autofill_manager();
     autofill_manager->client()->HideAutofillPopup(PopupHidingReason::kTabGone);
     test::ReenableSystemServices();
@@ -1026,7 +1026,7 @@
       web_contents());
   base::RunLoop run_loop;
   EXPECT_CALL(
-      *injector.GetForFrame(web_contents()->GetMainFrame()),
+      *injector.GetForFrame(web_contents()->GetPrimaryMainFrame()),
       OnFormSubmittedImpl(_, _, mojom::SubmissionSource::FORM_SUBMISSION))
       .Times(1)
       .WillRepeatedly(
@@ -1044,7 +1044,7 @@
   MockAutofillManagerInjector<MockFormSubmissionAutofillManager> injector(
       web_contents());
   base::RunLoop run_loop;
-  EXPECT_CALL(*injector.GetForFrame(web_contents()->GetMainFrame()),
+  EXPECT_CALL(*injector.GetForFrame(web_contents()->GetPrimaryMainFrame()),
               OnFormSubmittedImpl(
                   _, _, mojom::SubmissionSource::PROBABLY_FORM_SUBMITTED))
       .Times(1)
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index 5d34bd2..2988f7cb 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -2964,7 +2964,7 @@
   bool IsPopupShown() {
     return !!static_cast<ChromeAutofillClient*>(
                  ContentAutofillDriverFactory::FromWebContents(GetWebContents())
-                     ->DriverForFrame(GetWebContents()->GetMainFrame())
+                     ->DriverForFrame(GetWebContents()->GetPrimaryMainFrame())
                      ->autofill_manager()
                      ->client())
                  ->popup_controller_for_testing();
@@ -2999,7 +2999,7 @@
   ~AutofillInteractiveFencedFrameTest() override = default;
 
   content::RenderFrameHost* primary_main_frame_host() {
-    return GetWebContents()->GetMainFrame();
+    return GetWebContents()->GetPrimaryMainFrame();
   }
 
   content::RenderFrameHost* LoadSubFrame(std::string relative_url) {
diff --git a/chrome/browser/autofill/autofill_metrics_browsertest.cc b/chrome/browser/autofill/autofill_metrics_browsertest.cc
index 57cc1278..3ef2410 100644
--- a/chrome/browser/autofill/autofill_metrics_browsertest.cc
+++ b/chrome/browser/autofill/autofill_metrics_browsertest.cc
@@ -94,7 +94,7 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
 
   // Make sure the UKM were logged for the main frame url and none for the
@@ -118,7 +118,7 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
 
   // Make sure the UKM were logged for the main frame url and none for the
@@ -165,7 +165,7 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
 
   // Make sure the UKM were logged for the main frame url and none for the
@@ -190,7 +190,7 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
 
   // Make sure the UKM were logged for the main frame url and none for the
@@ -235,9 +235,10 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
@@ -260,9 +261,10 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
@@ -308,9 +310,10 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
@@ -334,9 +337,10 @@
   EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
diff --git a/chrome/browser/autofill/autofill_uitest.cc b/chrome/browser/autofill/autofill_uitest.cc
index f2c3101..165fa8e 100644
--- a/chrome/browser/autofill/autofill_uitest.cc
+++ b/chrome/browser/autofill/autofill_uitest.cc
@@ -132,8 +132,9 @@
   ChromeAutofillClient::FromWebContents(GetWebContents())
       ->KeepPopupOpenForTesting();
   // Inject the test delegate into the BrowserAutofillManager of the main frame.
-  RenderFrameHostChanged(/* old_host = */ nullptr,
-                         /* new_host = */ GetWebContents()->GetMainFrame());
+  RenderFrameHostChanged(
+      /* old_host = */ nullptr,
+      /* new_host = */ GetWebContents()->GetPrimaryMainFrame());
   Observe(GetWebContents());
 
   // Wait for Personal Data Manager to be fully loaded to prevent that
@@ -259,7 +260,7 @@
 }
 
 content::RenderViewHost* AutofillUiTest::GetRenderViewHost() {
-  return GetWebContents()->GetMainFrame()->GetRenderViewHost();
+  return GetWebContents()->GetPrimaryMainFrame()->GetRenderViewHost();
 }
 
 BrowserAutofillManager* AutofillUiTest::GetBrowserAutofillManager() {
diff --git a/chrome/browser/autofill/captured_sites_test_utils.cc b/chrome/browser/autofill/captured_sites_test_utils.cc
index 2e1e6cd..2a94cc12 100644
--- a/chrome/browser/autofill/captured_sites_test_utils.cc
+++ b/chrome/browser/autofill/captured_sites_test_utils.cc
@@ -1706,7 +1706,7 @@
     return false;
   }
   if (!is_iframe_container.value_or(false)) {
-    *frame = GetWebContents()->GetMainFrame();
+    *frame = GetWebContents()->GetPrimaryMainFrame();
     return true;
   }
 
diff --git a/chrome/browser/autofill/content_autofill_driver_browsertest.cc b/chrome/browser/autofill/content_autofill_driver_browsertest.cc
index 8969cd7..0b5e397 100644
--- a/chrome/browser/autofill/content_autofill_driver_browsertest.cc
+++ b/chrome/browser/autofill/content_autofill_driver_browsertest.cc
@@ -282,7 +282,7 @@
   // Set a dummy form data to simulate to submit a form. And, OnFormSubmitted
   // method will be called upon navigation.
   ContentAutofillDriverFactory::FromWebContents(web_contents())
-      ->DriverForFrame(web_contents()->GetMainFrame())
+      ->DriverForFrame(web_contents()->GetPrimaryMainFrame())
       ->SetFormToBeProbablySubmitted(absl::make_optional<FormData>());
 
   base::HistogramTester histogram_tester;
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index 50ffcab..36b47d3 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -245,7 +245,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   ContentAutofillDriver* autofill_driver =
       ContentAutofillDriverFactory::FromWebContents(web_contents)
-          ->DriverForFrame(web_contents->GetMainFrame());
+          ->DriverForFrame(web_contents->GetPrimaryMainFrame());
   ASSERT_NE(nullptr, autofill_driver);
   AutofillManager* autofill_manager = autofill_driver->autofill_manager();
   ASSERT_NE(nullptr, autofill_manager);
diff --git a/chrome/browser/background_fetch/background_fetch_browsertest.cc b/chrome/browser/background_fetch/background_fetch_browsertest.cc
index 711cda0..570321de 100644
--- a/chrome/browser/background_fetch/background_fetch_browsertest.cc
+++ b/chrome/browser/background_fetch/background_fetch_browsertest.cc
@@ -360,7 +360,7 @@
     return content::ExecuteScriptAndExtractString(
         active_browser_->tab_strip_model()
             ->GetActiveWebContents()
-            ->GetMainFrame(),
+            ->GetPrimaryMainFrame(),
         script, result);
   }
 
@@ -1001,9 +1001,11 @@
   // Load a fenced frame.
   GURL fenced_frame_url(https_server()->GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame =
-      fenced_frame_test_helper().CreateFencedFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                   fenced_frame_url);
 
   GURL fenced_frame_test_url(
       https_server()->GetURL("/fenced_frames/background_fetch.html"));
@@ -1043,9 +1045,11 @@
   GURL fenced_frame_url(
       cross_origin_server.GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame =
-      fenced_frame_test_helper().CreateFencedFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                   fenced_frame_url);
 
   GURL fenced_frame_test_url(
       cross_origin_server.GetURL("/fenced_frames/background_fetch.html"));
diff --git a/chrome/browser/background_fetch/background_fetch_permission_context_unittest.cc b/chrome/browser/background_fetch/background_fetch_permission_context_unittest.cc
index e43a2a1..0b1d0eb 100644
--- a/chrome/browser/background_fetch/background_fetch_permission_context_unittest.cc
+++ b/chrome/browser/background_fetch/background_fetch_permission_context_unittest.cc
@@ -39,7 +39,7 @@
 
     if (with_frame) {
       content::WebContentsTester::For(web_contents())->NavigateAndCommit(url);
-      render_frame_host = web_contents()->GetMainFrame();
+      render_frame_host = web_contents()->GetPrimaryMainFrame();
     }
 
     auto permission_result = permission_context->GetPermissionStatus(
diff --git a/chrome/browser/background_sync/background_sync_browsertest.cc b/chrome/browser/background_sync/background_sync_browsertest.cc
index 2de0fba..e4de859 100644
--- a/chrome/browser/background_sync/background_sync_browsertest.cc
+++ b/chrome/browser/background_sync/background_sync_browsertest.cc
@@ -69,9 +69,11 @@
 
   // Runs the |script| in the current tab and writes the output to |*result|.
   bool RunScript(const std::string& script, std::string* result) {
-    return content::ExecuteScriptAndExtractString(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        script, result);
+    return content::ExecuteScriptAndExtractString(browser()
+                                                      ->tab_strip_model()
+                                                      ->GetActiveWebContents()
+                                                      ->GetPrimaryMainFrame(),
+                                                  script, result);
   }
 
   // Intercepts all requests.
diff --git a/chrome/browser/background_sync/background_sync_delegate_impl.cc b/chrome/browser/background_sync/background_sync_delegate_impl.cc
index 8aafd40..f287377 100644
--- a/chrome/browser/background_sync/background_sync_delegate_impl.cc
+++ b/chrome/browser/background_sync/background_sync_delegate_impl.cc
@@ -162,7 +162,8 @@
   suspended_periodic_sync_origins_.erase(iter);
 
   // Engagement is always accumulated in the main frame.
-  auto* storage_partition = web_contents->GetMainFrame()->GetStoragePartition();
+  auto* storage_partition =
+      web_contents->GetPrimaryMainFrame()->GetStoragePartition();
   if (!storage_partition)
     return;
 
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
index 18ffbee..30c68ba7 100644
--- a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
@@ -90,7 +90,7 @@
 
     if (with_frame) {
       content::WebContentsTester::For(web_contents())->NavigateAndCommit(url);
-      render_frame_host = web_contents()->GetMainFrame();
+      render_frame_host = web_contents()->GetPrimaryMainFrame();
     }
 
     auto permission_result = permission_context_->GetPermissionStatus(
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index 31e790a..3c602036 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -866,7 +866,7 @@
       "manifest.json");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
   EXPECT_EQ(manager->state(), AppBannerManager::State::INACTIVE);
 
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
index ea3ae457..dc7d461 100644
--- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
+++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -527,9 +527,10 @@
   }
 
   void CheckLastCommitedOrigin(const std::string& pattern) {
-    EXPECT_THAT(
-        web_contents_->GetMainFrame()->GetLastCommittedOrigin().Serialize(),
-        testing::StartsWith(pattern));
+    EXPECT_THAT(web_contents_->GetPrimaryMainFrame()
+                    ->GetLastCommittedOrigin()
+                    .Serialize(),
+                testing::StartsWith(pattern));
   }
 
   std::unique_ptr<device::BluetoothAdapterFactory::GlobalValuesForTesting>
@@ -566,7 +567,7 @@
 
   // Crash the renderer process.
   content::RenderProcessHost* process =
-      web_contents_->GetMainFrame()->GetProcess();
+      web_contents_->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   process->Shutdown(0);
@@ -845,8 +846,8 @@
 
   // Attempting to access bluetooth devices from a disallowed iframe should
   // throw a SecurityError.
-  content::EvalJsResult inner_device_error =
-      InvokeGetDevices(content::ChildFrameAt(web_contents_->GetMainFrame(), 0));
+  content::EvalJsResult inner_device_error = InvokeGetDevices(
+      content::ChildFrameAt(web_contents_->GetPrimaryMainFrame(), 0));
   EXPECT_EQ(
       "SecurityError: Failed to execute 'getDevices' on 'Bluetooth': Access to "
       "the feature \"bluetooth\" is disallowed by permissions policy.",
@@ -869,8 +870,8 @@
   // has requested.
   content::EvalJsResult outer_device_id =
       InvokeRequestDevice(web_contents_.get());
-  content::EvalJsResult inner_device_id =
-      InvokeGetDevices(content::ChildFrameAt(web_contents_->GetMainFrame(), 0));
+  content::EvalJsResult inner_device_id = InvokeGetDevices(
+      content::ChildFrameAt(web_contents_->GetPrimaryMainFrame(), 0));
   ASSERT_TRUE(outer_device_id.value.is_list()) << outer_device_id.value;
   ASSERT_TRUE(inner_device_id.value.is_list()) << inner_device_id.value;
   EXPECT_EQ(outer_device_id.ExtractList(), inner_device_id.ExtractList());
@@ -901,7 +902,7 @@
   // The main page should have access to the same devices that the inner frame
   // has requested.
   content::EvalJsResult inner_device_id = InvokeRequestDevice(
-      content::ChildFrameAt(web_contents_->GetMainFrame(), 0));
+      content::ChildFrameAt(web_contents_->GetPrimaryMainFrame(), 0));
   content::EvalJsResult outer_device_id = InvokeGetDevices(web_contents_.get());
   ASSERT_TRUE(outer_device_id.value.is_list()) << outer_device_id.value;
   ASSERT_TRUE(inner_device_id.value.is_list()) << inner_device_id.value;
@@ -1228,7 +1229,8 @@
 
   permissions::BluetoothChooserContext* context =
       BluetoothChooserContextFactory::GetForProfile(browser()->profile());
-  url::Origin origin = web_contents_->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin();
 
   // Revoke the permission.
   const auto objects = context->GetGrantedObjects(origin);
@@ -1285,7 +1287,8 @@
     })()
   )"));
 
-  url::Origin origin = web_contents_->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   permissions::BluetoothChooserContext* context =
       BluetoothChooserContextFactory::GetForProfile(browser()->profile());
   auto objects = context->GetGrantedObjects(origin);
@@ -1481,7 +1484,7 @@
   EXPECT_FALSE(observer.last_is_connected_to_bluetooth_device().has_value());
 
   content::RenderFrameDeletedObserver rfh_observer(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
 
   // Navigates the primary page to the URL.
   prerender_helper()->NavigatePrimaryPage(prerender_url);
diff --git a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
index 92e4511..64f6082 100644
--- a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
+++ b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
@@ -237,7 +237,7 @@
   ASSERT_EQ(0ul,
             breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
   auto simulator = content::NavigationSimulator::CreateRendererInitiated(
-      GURL(), web_contents()->GetMainFrame());
+      GURL(), web_contents()->GetPrimaryMainFrame());
   simulator->SetHasUserGesture(true);
   simulator->SetTransition(ui::PAGE_TRANSITION_LINK);
   simulator->Start();
@@ -262,7 +262,7 @@
   ASSERT_EQ(0ul,
             breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
   auto simulator = content::NavigationSimulator::CreateRendererInitiated(
-      GURL(), web_contents()->GetMainFrame());
+      GURL(), web_contents()->GetPrimaryMainFrame());
   simulator->SetHasUserGesture(false);
   simulator->Start();
   const std::list<std::string> events =
@@ -350,7 +350,7 @@
             breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
 
   static_cast<content::TestWebContents*>(web_contents())
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->DidFailLoadWithError(GURL(), net::ERR_ABORTED);
   const std::list<std::string> events =
       breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
diff --git a/chrome/browser/browser_commands_unittest.cc b/chrome/browser/browser_commands_unittest.cc
index d1b9e2b6..2e560d7 100644
--- a/chrome/browser/browser_commands_unittest.cc
+++ b/chrome/browser/browser_commands_unittest.cc
@@ -132,8 +132,10 @@
   // Navigate to a URL and simulate a subframe committing.
   AddTab(browser(), url1);
   content::RenderFrameHostTester* rfh_tester =
-      content::RenderFrameHostTester::For(
-          browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame());
+      content::RenderFrameHostTester::For(browser()
+                                              ->tab_strip_model()
+                                              ->GetWebContentsAt(0)
+                                              ->GetPrimaryMainFrame());
   content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe");
   content::NavigationSimulator::NavigateAndCommitFromDocument(
       GURL(url1_subframe), subframe);
diff --git a/chrome/browser/browsing_data/access_context_audit_browsertest.cc b/chrome/browser/browsing_data/access_context_audit_browsertest.cc
index 355f70d9..8d274a4 100644
--- a/chrome/browser/browsing_data/access_context_audit_browsertest.cc
+++ b/chrome/browser/browsing_data/access_context_audit_browsertest.cc
@@ -146,7 +146,7 @@
 // Calls the accessStorage javascript function and awaits its completion for
 // each frame in the active web contents for |browser|.
 void EnsurePageAccessedStorage(content::WebContents* web_contents) {
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating([](content::RenderFrameHost* frame) {
         EXPECT_TRUE(
             content::EvalJs(frame,
@@ -681,7 +681,7 @@
   ASSERT_TRUE(content::NavigateToURL(
       GetWebContents(), top_level_.GetURL(kTopLevelHost, "/empty.html")));
   content::RenderFrameHost* ff = fenced_frame_test_helper().CreateFencedFrame(
-      GetWebContents()->GetMainFrame(), embedded_url());
+      GetWebContents()->GetPrimaryMainFrame(), embedded_url());
 
   EXPECT_TRUE(
       content::EvalJs(ff, "(async () => { return await accessStorage();})()")
diff --git a/chrome/browser/browsing_data/third_party_data_remover_browsertest.cc b/chrome/browser/browsing_data/third_party_data_remover_browsertest.cc
index ce9d8a11d..b53c148 100644
--- a/chrome/browser/browsing_data/third_party_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/third_party_data_remover_browsertest.cc
@@ -132,7 +132,7 @@
   content::RenderFrameHost* GetFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return ChildFrameAt(web_contents->GetMainFrame(), 0);
+    return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   }
 
   void AddStorage(const std::string& top_level_host,
diff --git a/chrome/browser/browsing_topics/browsing_topics_internals_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_internals_browsertest.cc
index 24b6924..dbae42cf 100644
--- a/chrome/browser/browsing_topics/browsing_topics_internals_browsertest.cc
+++ b/chrome/browser/browsing_topics/browsing_topics_internals_browsertest.cc
@@ -103,7 +103,7 @@
   // to execute the script because WebUI has a default CSP policy denying
   // "eval()", which is what EvalJs uses under the hood.
   std::string EvalJsInWebUI(const std::string& script) {
-    return content::EvalJs(web_contents()->GetMainFrame(), script,
+    return content::EvalJs(web_contents()->GetPrimaryMainFrame(), script,
                            content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
                            /*world_id=*/1)
         .ExtractString();
@@ -579,7 +579,8 @@
     document.querySelector('#hosts-classification-button').click();
   )";
 
-  EXPECT_TRUE(ExecJs(web_contents()->GetMainFrame(), classify_hosts_script,
+  EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
+                     classify_hosts_script,
                      content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
                      /*world_id=*/1));
 
@@ -615,7 +616,8 @@
     document.querySelector('#hosts-classification-button').click();
   )";
 
-  EXPECT_TRUE(ExecJs(web_contents()->GetMainFrame(), classify_hosts_script,
+  EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
+                     classify_hosts_script,
                      content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
                      /*world_id=*/1));
 
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
index fc118bf..09fe5ed 100644
--- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
+++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -674,7 +674,7 @@
 
   std::vector<privacy_sandbox::CanonicalTopic> result =
       browsing_topics_service()->GetTopicsForSiteForDisplay(
-          web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+          web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Epoch switch time has not arrived. So expect one topic from each of the
   // first two epochs.
@@ -753,8 +753,8 @@
                                            /*iframe_id=*/"frame",
                                            subframe_url));
 
-  std::string result =
-      InvokeTopicsAPI(content::ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  std::string result = InvokeTopicsAPI(
+      content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   EXPECT_TRUE(result == kExpectedResultOrder1 ||
               result == kExpectedResultOrder2);
@@ -776,7 +776,7 @@
 
   // b.test has yet to call the API so it shouldn't receive a topic.
   EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
-                      web_contents()->GetMainFrame(), 0)));
+                      web_contents()->GetPrimaryMainFrame(), 0)));
   auto* pscs = content_settings::PageSpecificContentSettings::GetForPage(
       web_contents()->GetPrimaryPage());
   EXPECT_FALSE(pscs->HasAccessedTopics());
@@ -803,7 +803,7 @@
   EXPECT_EQ(api_usage_contexts.size(), 1u);
 
   EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
-                      web_contents()->GetMainFrame(), 0)));
+                      web_contents()->GetPrimaryMainFrame(), 0)));
 
   api_usage_contexts =
       content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager());
@@ -872,7 +872,7 @@
       "The \"browsing-topics\" Permissions Policy denied the use of "
       "document.browsingTopics().",
       InvokeTopicsAPI(
-          content::ChildFrameAt(web_contents()->GetMainFrame(), 0)));
+          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
@@ -900,7 +900,7 @@
                                            /*iframe_id=*/"frame",
                                            subframe_url));
   EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
-                      web_contents()->GetMainFrame(), 0)));
+                      web_contents()->GetPrimaryMainFrame(), 0)));
 
   subframe_url =
       https_server_.GetURL("b.test", "/browsing_topics/empty_page.html");
@@ -913,7 +913,7 @@
       "The \"browsing-topics\" Permissions Policy denied the use of "
       "document.browsingTopics().",
       InvokeTopicsAPI(
-          content::ChildFrameAt(web_contents()->GetMainFrame(), 0)));
+          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
@@ -933,7 +933,7 @@
   // frame.
   EXPECT_EQ("not a function", InvokeTopicsAPI(web_contents()));
   EXPECT_EQ("not a function", InvokeTopicsAPI(content::ChildFrameAt(
-                                  web_contents()->GetMainFrame(), 0)));
+                                  web_contents()->GetPrimaryMainFrame(), 0)));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
@@ -967,7 +967,7 @@
   EXPECT_EQ(
       "document.browsingTopics() is not allowed in an opaque origin context.",
       InvokeTopicsAPI(
-          content::ChildFrameAt(web_contents()->GetMainFrame(), 0)));
+          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
@@ -982,7 +982,7 @@
 
   content::RenderFrameHostWrapper fenced_frame_rfh_wrapper(
       fenced_frame_test_helper_.CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url));
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url));
 
   EXPECT_EQ(
       "document.browsingTopics() is only allowed in the primary main frame or "
diff --git a/chrome/browser/capability_delegation_browsertest.cc b/chrome/browser/capability_delegation_browsertest.cc
index 3df0514..6b058314 100644
--- a/chrome/browser/capability_delegation_browsertest.cc
+++ b/chrome/browser/capability_delegation_browsertest.cc
@@ -64,10 +64,11 @@
   // Confirm that the subframe is cross-process depending on the process
   // model.
   content::RenderFrameHost* frame_host =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(frame_host);
   EXPECT_EQ(cross_site_url, frame_host->GetLastCommittedURL());
-  auto* main_instance = active_web_contents->GetMainFrame()->GetSiteInstance();
+  auto* main_instance =
+      active_web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   auto* subframe_instance = frame_host->GetSiteInstance();
   if (main_instance->RequiresDedicatedProcess()) {
     // Subframe is cross process because it can't be place in the main frame's
@@ -137,7 +138,7 @@
 
   // Confirm that the subframe is same-process.
   content::RenderFrameHost* frame_host =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(frame_host);
   EXPECT_EQ(subframe_url, frame_host->GetLastCommittedURL());
   EXPECT_FALSE(frame_host->IsCrossProcessSubframe());
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc
index f14e5ea..4c54dd8d 100644
--- a/chrome/browser/captive_portal/captive_portal_browsertest.cc
+++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -2018,7 +2018,7 @@
   // Wait for the interstitial to load all the JavaScript code. Otherwise,
   // trying to click on a button will fail.
   content::RenderFrameHost* rfh;
-  rfh = broken_tab_contents->GetMainFrame();
+  rfh = broken_tab_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(WaitForRenderFrameReady(rfh));
   const char kClickConnectButtonJS[] =
       "document.getElementById('primary-button').click();";
diff --git a/chrome/browser/cart/cart_metrics_tracker.cc b/chrome/browser/cart/cart_metrics_tracker.cc
index a5e08954..7abe2d1 100644
--- a/chrome/browser/cart/cart_metrics_tracker.cc
+++ b/chrome/browser/cart/cart_metrics_tracker.cc
@@ -36,7 +36,7 @@
   if (last_interacted_url_) {
     if (last_interacted_url_ == contents->GetVisibleURL()) {
       ukm::builders::Shopping_ChromeCart(
-          contents->GetMainFrame()->GetPageUkmSourceId())
+          contents->GetPrimaryMainFrame()->GetPageUkmSourceId())
           .SetVisitCart(true)
           .Record(ukm::UkmRecorder::Get());
     }
diff --git a/chrome/browser/cart/commerce_hint_service.cc b/chrome/browser/cart/commerce_hint_service.cc
index 9dee310..b681468 100644
--- a/chrome/browser/cart/commerce_hint_service.cc
+++ b/chrome/browser/cart/commerce_hint_service.cc
@@ -279,7 +279,7 @@
   bool random = (bytes[0] >> 1) & 0x1;
   bool reported = report_truth ? is_purchase : random;
   ukm::builders::Shopping_FormSubmitted(
-      GetWebContents().GetMainFrame()->GetPageUkmSourceId())
+      GetWebContents().GetPrimaryMainFrame()->GetPageUkmSourceId())
       .SetIsTransaction(reported)
       .Record(ukm::UkmRecorder::Get());
   base::UmaHistogramBoolean("Commerce.Carts.FormSubmitIsTransaction", reported);
@@ -295,7 +295,7 @@
   bool random = (bytes[0] >> 1) & 0x1;
   bool reported = report_truth ? is_addtocart : random;
   ukm::builders::Shopping_WillSendRequest(
-      GetWebContents().GetMainFrame()->GetPageUkmSourceId())
+      GetWebContents().GetPrimaryMainFrame()->GetPageUkmSourceId())
       .SetIsAddToCart(reported)
       .Record(ukm::UkmRecorder::Get());
   base::UmaHistogramBoolean("Commerce.Carts.XHRIsAddToCart", reported);
diff --git a/chrome/browser/chrome_back_forward_cache_browsertest.cc b/chrome/browser/chrome_back_forward_cache_browsertest.cc
index d9cff155..67551c6 100644
--- a/chrome/browser/chrome_back_forward_cache_browsertest.cc
+++ b/chrome/browser/chrome_back_forward_cache_browsertest.cc
@@ -117,7 +117,7 @@
   }
 
   content::RenderFrameHost* current_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   void SetupFeaturesAndParameters() {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 40b0e5dd..0e6e2da8 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -879,7 +879,7 @@
     result = UnifiedAutoplayConfig::ShouldBlockAutoplay(profile)
                  ? blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired
                  : blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
-  } else if (web_contents->GetMainFrame()->IsFeatureEnabled(
+  } else if (web_contents->GetPrimaryMainFrame()->IsFeatureEnabled(
                  blink::mojom::PermissionsPolicyFeature::kAutoplay) &&
              IsAutoplayAllowedByPolicy(web_contents->GetOuterWebContents(),
                                        prefs)) {
@@ -1127,7 +1127,7 @@
                     has_user_gesture);
 
     if (!allowed) {
-      content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+      content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
       if (client) {
         client->LogWebFeatureForCurrentPage(
             rfh, blink::mojom::WebFeature::kExternalProtocolBlockedBySandbox);
@@ -3675,7 +3675,8 @@
   }
 
   UpdatePreferredColorScheme(
-      web_prefs, web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL(),
+      web_prefs,
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
       web_contents, GetWebTheme());
 
   web_prefs->translate_service_available = TranslateService::IsAvailable(prefs);
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc
index 2a47385..c6653c7 100644
--- a/chrome/browser/chrome_content_browser_client_browsertest.cc
+++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -173,16 +173,16 @@
   InstantService* instant_service =
       InstantServiceFactory::GetForProfile(browser()->profile());
   EXPECT_TRUE(instant_service->IsInstantProcess(
-      contents->GetMainFrame()->GetProcess()->GetID()));
-  EXPECT_EQ(contents->GetMainFrame()->GetSiteInstance()->GetSiteURL(),
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
+  EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
             ntp_site_instance->GetSiteURL());
 
   // Navigating to a non-NTP URL on ntp.com should not result in an Instant
   // process.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), isolated_url));
   EXPECT_FALSE(instant_service->IsInstantProcess(
-      contents->GetMainFrame()->GetProcess()->GetID()));
-  EXPECT_EQ(contents->GetMainFrame()->GetSiteInstance()->GetSiteURL(),
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
+  EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
             site_instance->GetSiteURL());
 }
 
@@ -227,7 +227,7 @@
   InstantService* instant_service =
       InstantServiceFactory::GetForProfile(browser()->profile());
   EXPECT_TRUE(instant_service->IsInstantProcess(
-      ntp_tab->GetMainFrame()->GetProcess()->GetID()));
+      ntp_tab->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Execute script that creates new window from ntp tab with
   // ntp.com/title1.html as target url. Host is same as remote-ntp host, yet
@@ -250,7 +250,7 @@
   EXPECT_EQ(generic_url, opened_tab->GetLastCommittedURL());
   // New created tab should not reside in an Instant process.
   EXPECT_FALSE(instant_service->IsInstantProcess(
-      opened_tab->GetMainFrame()->GetProcess()->GetID()));
+      opened_tab->GetPrimaryMainFrame()->GetProcess()->GetID()));
 }
 
 class PrefersColorSchemeTest : public testing::WithParamInterface<bool>,
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc
index 3da4faf..3933d4f 100644
--- a/chrome/browser/chrome_navigation_browsertest.cc
+++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -139,16 +139,16 @@
 
   content::TestNavigationObserver observer(web_contents);
   ASSERT_TRUE(content::ExecuteScript(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       base::StringPrintf("var iframe = document.getElementById('test');\n"
                          "iframe.setAttribute('src', '%s');\n",
                          iframe_target_url.spec().c_str())));
   observer.Wait();
 
   content::RenderFrameHost* frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(frame);
-  ASSERT_NE(frame, web_contents->GetMainFrame());
+  ASSERT_NE(frame, web_contents->GetPrimaryMainFrame());
 
   content::ContextMenuParams params;
   params.page_url = local_page_with_iframe_url;
@@ -287,10 +287,10 @@
                                  content::WebContents* new_contents) override {
     // Verify that the two WebContents are in a different process, SiteInstance
     // and BrowsingInstance from the old contents.
-    EXPECT_NE(main_contents->GetMainFrame()->GetProcess(),
-              new_contents->GetMainFrame()->GetProcess());
-    EXPECT_NE(main_contents->GetMainFrame()->GetSiteInstance(),
-              new_contents->GetMainFrame()->GetSiteInstance());
+    EXPECT_NE(main_contents->GetPrimaryMainFrame()->GetProcess(),
+              new_contents->GetPrimaryMainFrame()->GetProcess());
+    EXPECT_NE(main_contents->GetPrimaryMainFrame()->GetSiteInstance(),
+              new_contents->GetPrimaryMainFrame()->GetSiteInstance());
     EXPECT_FALSE(main_contents->GetSiteInstance()->IsRelatedSiteInstance(
         new_contents->GetSiteInstance()));
   }
@@ -324,10 +324,11 @@
                                  content::WebContents* contents2) override {
     // Verify that the two WebContents are in the same process, though different
     // SiteInstance and BrowsingInstance from the old contents.
-    EXPECT_EQ(contents1->GetMainFrame()->GetProcess(),
-              contents2->GetMainFrame()->GetProcess());
-    EXPECT_EQ(contents1->GetMainFrame()->GetSiteInstance()->GetSiteURL(),
-              contents2->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+    EXPECT_EQ(contents1->GetPrimaryMainFrame()->GetProcess(),
+              contents2->GetPrimaryMainFrame()->GetProcess());
+    EXPECT_EQ(
+        contents1->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
+        contents2->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
     EXPECT_FALSE(contents1->GetSiteInstance()->IsRelatedSiteInstance(
         contents2->GetSiteInstance()));
   }
@@ -370,7 +371,7 @@
 
   ui_test_utils::TabAddedWaiter tab_add(browser());
 
-  TestRenderViewContextMenu menu(*web_contents->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents->GetPrimaryMainFrame(), params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -549,7 +550,7 @@
   // execute.  Since ExecuteScript will execute the passed-in script regardless
   // of CSP, use a javascript: URL which does go through the CSP checks.
   content::RenderFrameHost* error_host =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   std::string location;
   EXPECT_TRUE(ExecuteScriptAndExtractString(
       error_host,
@@ -589,7 +590,7 @@
                             "document.body.appendChild(frame);"));
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
   content::RenderFrameHost* subframe_host =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   // The new subframe should remain blank without a committed URL.
   EXPECT_TRUE(subframe_host->GetLastCommittedURL().is_empty());
 
@@ -667,8 +668,9 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_FALSE(observer.last_navigation_succeeded());
     EXPECT_EQ(url, observer.last_navigation_url());
-    EXPECT_EQ(GURL(content::kUnreachableWebDataURL),
-              web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+    EXPECT_EQ(
+        GURL(content::kUnreachableWebDataURL),
+        web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
   }
 
   // Install an extension, which will redirect all navigations to a.com URLs to
@@ -709,8 +711,9 @@
     observer.Wait();
     EXPECT_TRUE(observer.last_navigation_succeeded());
     EXPECT_EQ(GURL(url::kAboutBlankURL), observer.last_navigation_url());
-    EXPECT_NE(GURL(content::kUnreachableWebDataURL),
-              web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+    EXPECT_NE(
+        GURL(content::kUnreachableWebDataURL),
+        web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
   }
 }
 
@@ -766,8 +769,10 @@
 
   // 2. Open a popup containing a cross-site subframe.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kOpenerUrl));
-  content::RenderFrameHost* opener =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* opener = browser()
+                                         ->tab_strip_model()
+                                         ->GetActiveWebContents()
+                                         ->GetPrimaryMainFrame();
   EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL());
   EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin());
   content::WebContents* popup = nullptr;
@@ -781,7 +786,7 @@
   }
 
   // 3. Find the cross-site subframes in the popup.
-  content::RenderFrameHost* popup_root = popup->GetMainFrame();
+  content::RenderFrameHost* popup_root = popup->GetPrimaryMainFrame();
   content::RenderFrameHost* cross_site_subframe =
       content::ChildFrameAt(popup_root, 0);
   ASSERT_TRUE(cross_site_subframe);
@@ -811,7 +816,8 @@
                      content::JsReplace("top.location = $1", kRedirectedUrl)));
   nav_observer.Wait();
   EXPECT_EQ(url::kAboutBlankURL, popup->GetLastCommittedURL());
-  EXPECT_EQ(cross_site_origin, popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(cross_site_origin,
+            popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // 5. Verify that the about:blank URL is hosted in the same SiteInstance
   //    as the navigation initiator (and separate from the opener and the old
@@ -904,8 +910,10 @@
 
   // 2. Open a popup containing a cross-site subframe.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kOpenerUrl));
-  content::RenderFrameHost* opener =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* opener = browser()
+                                         ->tab_strip_model()
+                                         ->GetActiveWebContents()
+                                         ->GetPrimaryMainFrame();
   EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL());
   EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin());
   content::WebContents* popup = nullptr;
@@ -919,7 +927,7 @@
   }
 
   // 3. Find the cross-site subframes in the popup.
-  content::RenderFrameHost* popup_root = popup->GetMainFrame();
+  content::RenderFrameHost* popup_root = popup->GetPrimaryMainFrame();
   content::RenderFrameHost* cross_site_subframe = ChildFrameAt(popup_root, 0);
   ASSERT_TRUE(cross_site_subframe);
   EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
@@ -946,7 +954,7 @@
                      content::JsReplace("top.location = $1", kRedirectedUrl)));
   nav_observer.Wait();
   EXPECT_EQ(kRedirectTargetUrl, popup->GetLastCommittedURL());
-  EXPECT_TRUE(popup->GetMainFrame()->GetLastCommittedOrigin().opaque());
+  EXPECT_TRUE(popup->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
 
   // 5. Verify that with strict SiteInstances the data: URL is hosted in a brand
   //    new, separate SiteInstance (separate from the opener and the previous
@@ -990,8 +998,10 @@
                        SameDocumentNavigationInIframeInBlankDocument) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
-  content::RenderFrameHost* opener =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* opener = browser()
+                                         ->tab_strip_model()
+                                         ->GetActiveWebContents()
+                                         ->GetPrimaryMainFrame();
 
   // 1. Create a new blank window that stays on the initial NavigationEntry.
   content::WebContents* popup = nullptr;
@@ -1003,7 +1013,7 @@
                            embedded_test_server()->GetURL("/nocontent"))));
     popup = popup_observer.GetWebContents();
   }
-  content::RenderFrameHost* popup_main_rfh = popup->GetMainFrame();
+  content::RenderFrameHost* popup_main_rfh = popup->GetPrimaryMainFrame();
   // Popup should be on the initial entry, or no NavigationEntry if
   // InitialNavigationEntry is disabled.
   content::NavigationEntry* last_entry =
@@ -1037,8 +1047,10 @@
                        SameDocumentNavigationInBlankPopup) {
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-  content::RenderFrameHost* opener =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* opener = browser()
+                                         ->tab_strip_model()
+                                         ->GetActiveWebContents()
+                                         ->GetPrimaryMainFrame();
 
   // 1. Create a new blank window that will stay on the initial NavigationEntry.
   content::WebContents* popup = nullptr;
@@ -1123,7 +1135,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   scoped_refptr<content::SiteInstance> first_instance(
-      web_contents->GetMainFrame()->GetSiteInstance());
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Make sure that a renderer-initiated navigation to the sign-in page swaps
   // processes.
@@ -1131,7 +1143,8 @@
   EXPECT_TRUE(
       ExecuteScript(web_contents, "location = '" + signin_url.spec() + "';"));
   manager.WaitForNavigationFinished();
-  EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), first_instance);
+  EXPECT_NE(web_contents->GetPrimaryMainFrame()->GetSiteInstance(),
+            first_instance);
 }
 
 class WebstoreIsolationBrowserTest : public ChromeNavigationBrowserTest {
@@ -1205,10 +1218,12 @@
   EXPECT_TRUE(content::WaitForLoadStop(popup));
 
   scoped_refptr<content::SiteInstance> popup_instance(
-      popup->GetMainFrame()->GetSiteInstance());
-  EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), popup_instance);
-  EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance()->GetProcess(),
-            popup_instance->GetProcess());
+      popup->GetPrimaryMainFrame()->GetSiteInstance());
+  EXPECT_NE(web_contents->GetPrimaryMainFrame()->GetSiteInstance(),
+            popup_instance);
+  EXPECT_NE(
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetProcess(),
+      popup_instance->GetProcess());
 
   // Also navigate the popup to the full web store URL and confirm that this
   // causes a BrowsingInstance swap.
@@ -1218,13 +1233,15 @@
   EXPECT_TRUE(
       ExecuteScript(popup, "location = '" + webstore_url.spec() + "';"));
   manager.WaitForNavigationFinished();
-  EXPECT_NE(popup->GetMainFrame()->GetSiteInstance(), popup_instance);
-  EXPECT_NE(popup->GetMainFrame()->GetSiteInstance(),
-            web_contents->GetMainFrame()->GetSiteInstance());
-  EXPECT_FALSE(popup->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-      popup_instance.get()));
-  EXPECT_FALSE(popup->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-      web_contents->GetMainFrame()->GetSiteInstance()));
+  EXPECT_NE(popup->GetPrimaryMainFrame()->GetSiteInstance(), popup_instance);
+  EXPECT_NE(popup->GetPrimaryMainFrame()->GetSiteInstance(),
+            web_contents->GetPrimaryMainFrame()->GetSiteInstance());
+  EXPECT_FALSE(
+      popup->GetPrimaryMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
+          popup_instance.get()));
+  EXPECT_FALSE(
+      popup->GetPrimaryMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
+          web_contents->GetPrimaryMainFrame()->GetSiteInstance()));
 }
 
 // Check that it's possible to navigate to a chrome scheme URL from a crashed
@@ -1234,7 +1251,7 @@
   content::RenderProcessHost* process = browser()
                                             ->tab_strip_model()
                                             ->GetActiveWebContents()
-                                            ->GetMainFrame()
+                                            ->GetPrimaryMainFrame()
                                             ->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
@@ -1593,7 +1610,8 @@
   ASSERT_FALSE(sad_tab_helper->sad_tab());
 
   // Kill the renderer process.
-  content::RenderProcessHost* process = contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* process =
+      contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   process->Shutdown(-1);
@@ -1655,7 +1673,8 @@
   ASSERT_FALSE(sad_tab_helper->sad_tab());
 
   // Kill the renderer process.
-  content::RenderProcessHost* process = contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* process =
+      contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   process->Shutdown(-1);
@@ -1995,8 +2014,9 @@
 
   // foo.com should not be isolated to start with. Verify that a cross-site
   // iframe does not become an OOPIF.
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
   std::string kAppendIframe = R"(
       var i = document.createElement('iframe');
       i.id = 'child';
@@ -2004,7 +2024,8 @@
   EXPECT_TRUE(ExecJs(contents, kAppendIframe));
   GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
   EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url));
-  content::RenderFrameHost* child = ChildFrameAt(contents->GetMainFrame(), 0);
+  content::RenderFrameHost* child =
+      ChildFrameAt(contents->GetPrimaryMainFrame(), 0);
   EXPECT_FALSE(child->IsCrossProcessSubframe());
 
   // Fill a form and submit through a <input type="submit"> button.
@@ -2020,11 +2041,12 @@
   // swapped BrowsingInstances and put the result of the form submission into a
   // dedicated process, locked to foo.com.  Check that a cross-site iframe now
   // becomes an OOPIF.
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
   EXPECT_TRUE(ExecJs(contents, kAppendIframe));
   EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url));
-  child = ChildFrameAt(contents->GetMainFrame(), 0);
+  child = ChildFrameAt(contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(child->IsCrossProcessSubframe());
 
   // Open a fresh tab (also forcing a new BrowsingInstance), navigate to
@@ -2039,7 +2061,7 @@
   EXPECT_TRUE(ExecJs(new_contents, kAppendIframe));
   EXPECT_TRUE(NavigateIframeToURL(new_contents, "child", bar_url));
   content::RenderFrameHost* new_child =
-      ChildFrameAt(new_contents->GetMainFrame(), 0);
+      ChildFrameAt(new_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(new_child->IsCrossProcessSubframe());
 }
 
@@ -2121,8 +2143,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), saved_url));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   // Check that saved.com and saved2.com were saved to disk.
   EXPECT_THAT(GetSavedIsolatedSites(),
@@ -2147,14 +2170,17 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), saved_url));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), saved2_url));
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), foo_url));
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
 }
 
 // Verify that trying to isolate a site multiple times will only save it to
@@ -2190,8 +2216,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(incognito, saved_url));
   content::WebContents* contents =
       incognito->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
 
   // Add an isolated site in incognito, and verify that while future
   // navigations to this site in incognito require a dedicated process,
@@ -2204,14 +2231,16 @@
   AddBlankTabAndShow(incognito);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(incognito, foo_url));
   contents = incognito->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   AddBlankTabAndShow(browser());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), foo_url));
   contents = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
 
   EXPECT_THAT(GetSavedIsolatedSites(browser()->profile()),
               testing::Not(testing::Contains("http://foo.com")));
@@ -2300,7 +2329,7 @@
       https_server()->GetURL("www.oauthclient.com", "/title1.html")));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(contents->GetMainFrame()
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
                    ->GetProcess()
                    ->IsProcessLockedToSiteForTesting());
 
@@ -2342,7 +2371,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(),
       https_server()->GetURL("www2.oauthclient.com", "/title1.html")));
-  EXPECT_TRUE(contents->GetMainFrame()
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
                   ->GetProcess()
                   ->IsProcessLockedToSiteForTesting());
 }
@@ -2360,7 +2389,7 @@
       browser(), https_server()->GetURL("oauthclient.com", "/title1.html")));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(contents->GetMainFrame()
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
                    ->GetProcess()
                    ->IsProcessLockedToSiteForTesting());
 
@@ -2414,7 +2443,7 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), https_server()->GetURL("oauthclient.com", "/title1.html")));
-  EXPECT_TRUE(new_contents->GetMainFrame()
+  EXPECT_TRUE(new_contents->GetPrimaryMainFrame()
                   ->GetProcess()
                   ->IsProcessLockedToSiteForTesting());
 }
@@ -2435,7 +2464,7 @@
       browser(), https_server()->GetURL("oauthclient.com", "/title1.html")));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(contents->GetMainFrame()
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
                   ->GetProcess()
                   ->IsProcessLockedToSiteForTesting());
 }
@@ -2518,14 +2547,16 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), coop_url));
   // Simulate user activation.
   EXPECT_TRUE(ExecJs(contents, "// no-op"));
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), coop_url2));
   // Simulate user activation.
   EXPECT_TRUE(ExecJs(contents, "// no-op"));
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   // Check that saved.com and saved2.com were saved to disk.
   EXPECT_THAT(GetSavedIsolatedSites(browser()->profile()),
@@ -2546,18 +2577,21 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), saved_url));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), saved2_url));
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   // Sanity check that an unrelated non-isolated foo.com URL does not require a
   // dedicated process.
   GURL foo_url(https_server()->GetURL("foo.com", "/title3.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), foo_url));
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
 }
 
 // Check that COOP sites are not persisted in Incognito; the isolation should
@@ -2574,8 +2608,9 @@
   // Simulate user activation to isolate foo.com for the rest of the incognito
   // session.
   EXPECT_TRUE(ExecJs(contents, "// no-op"));
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   // Check that navigations to foo.com (even without COOP) are isolated in
   // future BrowsingInstances in Incognito.
@@ -2583,15 +2618,17 @@
   GURL foo_url = https_server()->GetURL("foo.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(incognito, foo_url));
   contents = incognito->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_TRUE(contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->RequiresDedicatedProcess());
 
   // foo.com should not be isolated in the regular profile.
   AddBlankTabAndShow(browser());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), foo_url));
   contents = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(
-      contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->RequiresDedicatedProcess());
 
   // Neither profile should've saved foo.com to COOP isolated sites prefs.
   EXPECT_THAT(GetSavedIsolatedSites(browser()->profile()), IsEmpty());
diff --git a/chrome/browser/chrome_render_widget_host_browsertests.cc b/chrome/browser/chrome_render_widget_host_browsertests.cc
index 9afb8c2..c3f93fe 100644
--- a/chrome/browser/chrome_render_widget_host_browsertests.cc
+++ b/chrome/browser/chrome_render_widget_host_browsertests.cc
@@ -70,7 +70,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame_a = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame_a = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame_b = ChildFrameAt(main_frame_a, 0);
   ASSERT_NE(nullptr, child_frame_b);
   content::RenderFrameHost* child_frame_d = ChildFrameAt(main_frame_a, 1);
@@ -224,7 +224,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
 
   mojo::PendingAssociatedReceiver<blink::mojom::FrameWidget>
diff --git a/chrome/browser/chrome_security_exploit_browsertest.cc b/chrome/browser/chrome_security_exploit_browsertest.cc
index 9464f184..9d21e3df 100644
--- a/chrome/browser/chrome_security_exploit_browsertest.cc
+++ b/chrome/browser/chrome_security_exploit_browsertest.cc
@@ -150,7 +150,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
 
   // This IPC should result in a kill because the Chrome Web Store is not
   // allowed to commit in |rfh->GetProcess()|.
@@ -181,7 +181,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
 
   // This IPC should result in a kill because |ext_origin| is not allowed to
   // commit in |rfh->GetProcess()|.
@@ -212,7 +212,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
 
   // This IPC should result in a kill because extension URLs are not allowed to
   // commit in |rfh->GetProcess()|.
@@ -243,7 +243,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
 
   // This IPC should result in a kill because extension filesystem URLs are not
   // allowed to commit in |rfh->GetProcess()|.
@@ -274,8 +274,10 @@
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL("chrome://version")));
 
-  content::RenderFrameHost* rfh =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame();
 
   // Block the renderer on operation that never completes, to shield it from
   // receiving unexpected browser->renderer IPCs that might CHECK.
@@ -325,7 +327,10 @@
   ASSERT_FALSE(AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED));
   EXPECT_FALSE(content::WaitForLoadStop(
       browser()->tab_strip_model()->GetWebContentsAt(0)));
-  rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  rfh = browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame();
 
   // If the attack is unsuccessful, the navigation ends up in an error
   // page.
@@ -358,8 +363,10 @@
       embedded_test_server()->GetURL("a.root-servers.net", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
 
-  content::RenderFrameHost* rfh =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame();
 
   // Block the renderer on operation that never completes, to shield it from
   // receiving unexpected browser->renderer IPCs that might CHECK.
@@ -406,7 +413,10 @@
   ASSERT_FALSE(AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED));
   EXPECT_FALSE(content::WaitForLoadStop(
       browser()->tab_strip_model()->GetWebContentsAt(0)));
-  rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  rfh = browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame();
 
   // If the attack is unsuccessful, the navigation ends up in an error
   // page.
@@ -498,8 +508,10 @@
       browser(),
       embedded_test_server()->GetURL("a.root-servers.net", "/title1.html")));
 
-  content::RenderFrameHost* rfh =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame();
 
   content::RenderProcessHostBadMojoMessageWaiter crash_observer(
       rfh->GetProcess());
@@ -542,8 +554,10 @@
                           GURL("blob:" + target_origin + "/" + blob_path));
   storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(&intercept_hook);
 
-  content::RenderFrameHost* rfh =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame();
 
   content::RenderProcessHostBadMojoMessageWaiter crash_observer(
       rfh->GetProcess());
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc
index b9c9fe1..8a681a9 100644
--- a/chrome/browser/chrome_service_worker_browsertest.cc
+++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -176,8 +176,10 @@
 
     EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
 
-    content::RenderFrameHost* main_frame =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* main_frame = browser()
+                                               ->tab_strip_model()
+                                               ->GetActiveWebContents()
+                                               ->GetPrimaryMainFrame();
     EXPECT_TRUE(
         content_settings::PageSpecificContentSettings::GetForFrame(main_frame)
             ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
@@ -524,7 +526,7 @@
     browser()
         ->tab_strip_model()
         ->GetActiveWebContents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->ExecuteJavaScriptForTests(
             base::ASCIIToUTF16(js),
             base::BindOnce(
diff --git a/chrome/browser/chrome_shared_array_buffer_browsertest.cc b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
index 5c51ce5..8f821ea5 100644
--- a/chrome/browser/chrome_shared_array_buffer_browsertest.cc
+++ b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
@@ -117,7 +117,8 @@
   GURL sub_url = embedded_test_server()->GetURL("a.com", "/empty.html");
 
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
 
   EXPECT_TRUE(content::ExecJs(main_document, content::JsReplace(R"(
     g_sab_size = new Promise(resolve => {
@@ -148,7 +149,8 @@
   GURL sub_url = embedded_test_server()->GetURL("a.com", "/empty.html");
 
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
 
   EXPECT_TRUE(content::ExecJs(web_contents(), content::JsReplace(R"(
     g_sab_size = new Promise(resolve => {
diff --git a/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc b/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc
index 9f159482..8da8e61e 100644
--- a/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc
+++ b/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc
@@ -452,7 +452,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -495,7 +496,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -533,7 +535,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -572,7 +575,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -613,7 +617,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -656,7 +661,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
   LoadIFrame(url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -694,7 +700,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -738,7 +745,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -778,7 +786,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -818,7 +827,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -860,7 +870,8 @@
   EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
   LoadIFrame(sub_url);
 
-  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_document =
+      web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);
 
   EXPECT_EQ(true, content::ExecJs(main_document, R"(
@@ -1278,9 +1289,9 @@
       https_server().GetURL("a.com", "/cross_site_iframe_factory.html?a(a,b)");
   ASSERT_TRUE(content::NavigateToURL(web_contents(), url));
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 1);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 1);
 
   struct TestCase {
     const char* name;
@@ -1383,7 +1394,7 @@
 
   // Check that a same-origin access does not register use counters.
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(content::ExecJs(same_origin_subframe, "window.top.close()"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessClose, 0);
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessFromOtherPageClose, 0);
@@ -1397,7 +1408,7 @@
 
   // Check that a cross-origin access register use counters.
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(content::ExecJs(cross_origin_subframe, "window.top.close()"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessClose, 1);
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessFromOtherPageClose, 0);
@@ -1411,7 +1422,7 @@
 
   // Check that a same-origin access does not register use counters.
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(content::ExecJs(same_origin_subframe, "window.top[0]"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessIndexedGetter, 0);
   CheckCounter(
@@ -1419,7 +1430,7 @@
 
   // Check that a cross-origin access register use counters.
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 1);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 1);
   EXPECT_TRUE(content::ExecJs(cross_origin_subframe, "window.top[0]"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessIndexedGetter, 1);
   CheckCounter(
@@ -1440,7 +1451,7 @@
 
   // Check that a same-origin access does not register use counters.
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       content::ExecJs(same_origin_subframe,
                       content::JsReplace("window.top.location = $1", url)));
@@ -1459,7 +1470,7 @@
 
   // Check that a cross-origin access register use counters.
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 1);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 1);
   EXPECT_TRUE(content::ExecJs(
       cross_origin_subframe,
       content::JsReplace("window.top.location = $1", fragment_url)));
@@ -1478,7 +1489,7 @@
 
   // Check that a same-origin access does not register use counters.
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(content::ExecJs(same_origin_subframe,
                               "window.top['about_blank_iframe']"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessNamedGetter, 0);
@@ -1487,7 +1498,7 @@
 
   // Check that a cross-origin access register use counters.
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 1);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 1);
   EXPECT_TRUE(content::ExecJs(cross_origin_subframe,
                               "window.top['about_blank_iframe']"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessNamedGetter, 1);
@@ -1510,7 +1521,7 @@
 
   // Check that a same-origin access does not register use counters.
   content::RenderFrameHost* same_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(content::ExecJs(same_origin_subframe, "window.top.opener = ''"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessOpener, 0);
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessFromOtherPageOpener, 0);
@@ -1518,7 +1529,7 @@
   // Check that a cross-origin access doesn't register use counters because it
   // is blocked by the same-origin policy.
   content::RenderFrameHost* cross_origin_subframe =
-      ChildFrameAt(web_contents()->GetMainFrame(), 1);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 1);
   EXPECT_FALSE(
       content::ExecJs(cross_origin_subframe, "window.top.opener = ''"));
   CheckCounter(WebFeature::kWindowProxyCrossOriginAccessOpener, 0);
diff --git a/chrome/browser/chromeos/app_mode/chrome_kiosk_app_launcher_unittest.cc b/chrome/browser/chromeos/app_mode/chrome_kiosk_app_launcher_unittest.cc
index 2072241..51bad11 100644
--- a/chrome/browser/chromeos/app_mode/chrome_kiosk_app_launcher_unittest.cc
+++ b/chrome/browser/chromeos/app_mode/chrome_kiosk_app_launcher_unittest.cc
@@ -95,7 +95,7 @@
       app_window_contents->GetWebContents());
 
   content::RenderFrameHost* main_frame =
-      app_window_contents->GetWebContents()->GetMainFrame();
+      app_window_contents->GetWebContents()->GetPrimaryMainFrame();
   DCHECK(main_frame);
 
   extensions::AppWindow::CreateParams params;
diff --git a/chrome/browser/chromeos/extensions/default_keyboard_extension_browser_test.cc b/chrome/browser/chromeos/extensions/default_keyboard_extension_browser_test.cc
index 67879d8..baca814 100644
--- a/chrome/browser/chromeos/extensions/default_keyboard_extension_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/default_keyboard_extension_browser_test.cc
@@ -106,7 +106,8 @@
     if (!view)
       continue;
     content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
-    if (wc && url == wc->GetMainFrame()->GetSiteInstance()->GetSiteURL()) {
+    if (wc &&
+        url == wc->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL()) {
       // Waits for virtual keyboard to load.
       EXPECT_TRUE(content::WaitForLoadStop(wc));
       return wc;
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index a2fcbd1..3bdfda0 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -697,7 +697,7 @@
              "});"));
 
   content::UpdateUserActivationStateInterceptor user_activation_interceptor(
-      GetActiveWebContents()->GetMainFrame());
+      GetActiveWebContents()->GetPrimaryMainFrame());
   user_activation_interceptor.UpdateUserActivationState(
       blink::mojom::UserActivationUpdateType::kNotifyActivation,
       blink::mojom::UserActivationNotificationType::kTest);
@@ -792,7 +792,7 @@
              "});"));
 
   content::UpdateUserActivationStateInterceptor user_activation_interceptor(
-      GetActiveWebContents()->GetMainFrame());
+      GetActiveWebContents()->GetPrimaryMainFrame());
   user_activation_interceptor.UpdateUserActivationState(
       blink::mojom::UserActivationUpdateType::kNotifyActivation,
       blink::mojom::UserActivationNotificationType::kTest);
@@ -884,7 +884,7 @@
              "});"));
 
   content::UpdateUserActivationStateInterceptor user_activation_interceptor(
-      GetActiveWebContents()->GetMainFrame());
+      GetActiveWebContents()->GetPrimaryMainFrame());
   user_activation_interceptor.UpdateUserActivationState(
       blink::mojom::UserActivationUpdateType::kNotifyActivation,
       blink::mojom::UserActivationNotificationType::kTest);
@@ -967,7 +967,7 @@
              "});"));
 
   content::UpdateUserActivationStateInterceptor user_activation_interceptor(
-      GetActiveWebContents()->GetMainFrame());
+      GetActiveWebContents()->GetPrimaryMainFrame());
   user_activation_interceptor.UpdateUserActivationState(
       blink::mojom::UserActivationUpdateType::kNotifyActivation,
       blink::mojom::UserActivationNotificationType::kTest);
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index a186d0e..85fba72 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -202,7 +202,8 @@
       TestingProfile::Builder().Build();
   auto web_contents = CreateTestWebContents(testing_profile.get());
   dlp_controller_.PasteIfAllowed(&data_src, &data_dst, absl::nullopt,
-                                 web_contents->GetMainFrame(), callback.Get());
+                                 web_contents->GetPrimaryMainFrame(),
+                                 callback.Get());
 }
 
 TEST_F(DataTransferDlpControllerTest, PasteIfAllowed_NullWebContents) {
@@ -235,7 +236,8 @@
   EXPECT_CALL(dlp_controller_, WarnOnBlinkPaste);
 
   dlp_controller_.PasteIfAllowed(&data_src, &data_dst, absl::nullopt,
-                                 web_contents->GetMainFrame(), callback.Get());
+                                 web_contents->GetPrimaryMainFrame(),
+                                 callback.Get());
   // We are not expecting warning proceeded event here. Warning proceeded event
   // is sent after a user accept the warn dialogue.
   // However, DataTransferDlpController::WarnOnBlinkPaste method is mocked
@@ -266,7 +268,8 @@
 
   EXPECT_CALL(callback, Run(true));
   dlp_controller_.PasteIfAllowed(&data_src, &data_dst, absl::nullopt,
-                                 web_contents->GetMainFrame(), callback.Get());
+                                 web_contents->GetPrimaryMainFrame(),
+                                 callback.Get());
   EXPECT_EQ(events_.size(), 1u);
   EXPECT_THAT(events_[0],
               IsDlpPolicyEvent(CreateDlpPolicyWarningProceededEvent(
@@ -293,7 +296,8 @@
 
   EXPECT_CALL(callback, Run(false));
   dlp_controller_.PasteIfAllowed(&data_src, &data_dst, absl::nullopt,
-                                 web_contents->GetMainFrame(), callback.Get());
+                                 web_contents->GetPrimaryMainFrame(),
+                                 callback.Get());
   EXPECT_TRUE(events_.empty());
 }
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
index 96d72aa1..d374d88a 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
@@ -326,7 +326,7 @@
   // here explicitly.
   if (media_id_.type == content::DesktopMediaID::TYPE_WEB_CONTENTS &&
       web_contents_ && source_callback_) {
-    content::RenderFrameHost* main_frame = web_contents_->GetMainFrame();
+    content::RenderFrameHost* main_frame = web_contents_->GetPrimaryMainFrame();
     DCHECK(main_frame);
     source_callback_.Run(content::DesktopMediaID(
         content::DesktopMediaID::TYPE_WEB_CONTENTS,
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
index 63f8982..3823959 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
@@ -619,8 +619,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents->GetMainFrame()->GetProcess()->GetID(),
-          web_contents->GetMainFrame()->GetRoutingID()));
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents->GetPrimaryMainFrame()->GetRoutingID()));
 
   DlpContentManager* manager = helper_->GetContentManager();
   base::MockCallback<content::MediaStreamUI::StateChangeCallback>
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_browsertest.cc
index d07ab5c..7dc4c21c 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_browsertest.cc
@@ -140,7 +140,7 @@
               OnConfidentialityChanged(_, kScreenshotRestrictionSet))
       .Times(1);
   EXPECT_TRUE(content::NavigateToURL(web_contents, kUrlRestricted));
-  content::RenderFrameHost* const rfh_a = web_contents->GetMainFrame();
+  content::RenderFrameHost* const rfh_a = web_contents->GetPrimaryMainFrame();
   content::RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
 
   // 2) navigate to unrestricted.com
@@ -148,7 +148,7 @@
               OnConfidentialityChanged(_, kEmptyRestrictionSet))
       .Times(1);
   EXPECT_TRUE(content::NavigateToURL(web_contents, kUrlUnrestricted));
-  content::RenderFrameHost* const rfh_b = web_contents->GetMainFrame();
+  content::RenderFrameHost* const rfh_b = web_contents->GetPrimaryMainFrame();
   content::RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
 
   EXPECT_FALSE(delete_observer_rfh_a.deleted())
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_unittest.cc
index 651bbfd..66328971 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper_unittest.cc
@@ -173,9 +173,9 @@
       .Times(1);
   content::RenderFrameHost* subframe =
       content::NavigationSimulator::NavigateAndCommitFromDocument(
-          kConfidentialUrl,
-          content::RenderFrameHostTester::For(web_contents->GetMainFrame())
-              ->AppendChild("child"));
+          kConfidentialUrl, content::RenderFrameHostTester::For(
+                                web_contents->GetPrimaryMainFrame())
+                                ->AppendChild("child"));
 
   // Navigate away from confidential URL.
   EXPECT_CALL(mock_dlp_content_observer_,
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc
index b8193763..d2091733 100644
--- a/chrome/browser/client_hints/client_hints_browsertest.cc
+++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -518,7 +518,10 @@
   // blocked on the webpage due to the checks done by client hints.
   void VerifyContentSettingsNotNotified() const {
     auto* pscs = content_settings::PageSpecificContentSettings::GetForFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+        browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame());
     EXPECT_FALSE(pscs->IsContentBlocked(ContentSettingsType::COOKIES));
     EXPECT_FALSE(pscs->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
   }
diff --git a/chrome/browser/commerce/shopping_list/shopping_data_provider.cc b/chrome/browser/commerce/shopping_list/shopping_data_provider.cc
index ee5f466..fd1b652 100644
--- a/chrome/browser/commerce/shopping_list/shopping_data_provider.cc
+++ b/chrome/browser/commerce/shopping_list/shopping_data_provider.cc
@@ -83,7 +83,7 @@
   base::OnceCallback<void(base::Value)> callback =
       base::BindOnce(&ShoppingDataProvider::OnJavascriptExecutionCompleted,
                      weak_ptr_factory_.GetWeakPtr());
-  web_contents()->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(
+  web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld(
       base::UTF8ToUTF16(script), std::move(callback),
       ISOLATED_WORLD_ID_CHROME_INTERNAL);
 }
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
index 281cac7..5bb941e9 100644
--- a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
+++ b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
@@ -148,7 +148,7 @@
 
   // Check that the page is blocked depending on CT enforcement.
   content::WebContents* tab = chrome_test_utils::GetActiveWebContents(this);
-  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetMainFrame()));
+  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame()));
   if (GetParam() == CTEnforcement::kEnabled) {
     EXPECT_NE(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle());
   } else {
@@ -163,7 +163,7 @@
   // Check that the page is still blocked depending on CT enforcement.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), https_server_ok.GetURL("/simple.html")));
-  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetMainFrame()));
+  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame()));
   if (GetParam() == CTEnforcement::kEnabled) {
     EXPECT_NE(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle());
   } else {
@@ -251,7 +251,7 @@
 
   // Check that the page is blocked depending on contents of Chrome Root Store.
   content::WebContents* tab = chrome_test_utils::GetActiveWebContents(this);
-  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetMainFrame()));
+  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame()));
   EXPECT_NE(chrome_test_utils::GetActiveWebContents(this)->GetTitle(), u"OK");
   ssl_test_util::CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_AUTHORITY_INVALID,
@@ -288,7 +288,7 @@
 
   // Check that the page is allowed due to contents of Chrome Root Store.
   tab = chrome_test_utils::GetActiveWebContents(this);
-  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetMainFrame()));
+  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame()));
   EXPECT_EQ(chrome_test_utils::GetActiveWebContents(this)->GetTitle(), u"OK");
   ssl_test_util::CheckAuthenticatedState(tab, ssl_test_util::AuthState::NONE);
 
@@ -322,7 +322,7 @@
 
   // Check that the page is blocked depending on contents of Chrome Root Store.
   tab = chrome_test_utils::GetActiveWebContents(this);
-  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetMainFrame()));
+  ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame()));
   EXPECT_NE(chrome_test_utils::GetActiveWebContents(this)->GetTitle(), u"OK");
   ssl_test_util::CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_AUTHORITY_INVALID,
diff --git a/chrome/browser/content_index/content_index_browsertest.cc b/chrome/browser/content_index/content_index_browsertest.cc
index bed0a15..28b17ea6 100644
--- a/chrome/browser/content_index/content_index_browsertest.cc
+++ b/chrome/browser/content_index/content_index_browsertest.cc
@@ -148,7 +148,10 @@
  private:
   void RunScript(const std::string& script, std::string* result) {
     ASSERT_TRUE(content::ExecuteScriptAndExtractString(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+        browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame(),
         "WrapFunction(async () => " + script + ")", result));
     ASSERT_TRUE(
         base::StartsWith(*result, "ok - ", base::CompareCase::SENSITIVE))
diff --git a/chrome/browser/content_index/content_index_metrics.cc b/chrome/browser/content_index/content_index_metrics.cc
index 712783a..15f067a 100644
--- a/chrome/browser/content_index/content_index_metrics.cc
+++ b/chrome/browser/content_index/content_index_metrics.cc
@@ -58,7 +58,7 @@
   base::UmaHistogramEnumeration("ContentIndex.ContentOpened", category);
 
   ukm::builders::ContentIndex_Opened(
-      web_contents->GetMainFrame()->GetPageUkmSourceId())
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId())
       .SetIsOffline(net::NetworkChangeNotifier::IsOffline())
       .Record(ukm::UkmRecorder::Get());
 }
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index 2e9bf11..5dac0d2 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -89,16 +89,18 @@
 browsing_data::CannedCookieHelper* GetSiteSettingsCookieContainer(
     Browser* browser) {
   PageSpecificContentSettings* settings =
-      PageSpecificContentSettings::GetForFrame(
-          browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(browser->tab_strip_model()
+                                                   ->GetActiveWebContents()
+                                                   ->GetPrimaryMainFrame());
   return settings->allowed_local_shared_objects().cookies();
 }
 
 browsing_data::CannedCookieHelper* GetSiteSettingsBlockedCookieContainer(
     Browser* browser) {
   PageSpecificContentSettings* settings =
-      PageSpecificContentSettings::GetForFrame(
-          browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(browser->tab_strip_model()
+                                                   ->GetActiveWebContents()
+                                                   ->GetPrimaryMainFrame());
   return settings->blocked_local_shared_objects().cookies();
 }
 
@@ -309,8 +311,9 @@
 
   // Set a cookie by visiting a page that has a Set-Cookie header.
   void HttpWriteCookieWithURL(Browser* browser, const GURL& url) {
-    auto* frame =
-        browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    auto* frame = browser->tab_strip_model()
+                      ->GetActiveWebContents()
+                      ->GetPrimaryMainFrame();
     // Need to load via |frame| for the accessed/blocked cookies lists to be
     // updated properly.
     content::LoadBasicRequest(frame, url);
@@ -909,9 +912,9 @@
 
   ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(&observer));
 
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::COOKIES));
 }
 
 // Any cookie access during a navigation does not end up in a new document (e.g.
@@ -931,9 +934,9 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
 
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::COOKIES));
 }
 
 class ContentSettingsBackForwardCacheBrowserTest : public ContentSettingsTest {
@@ -974,25 +977,25 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
 
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::COOKIES));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), other_url));
   EXPECT_EQ(main_frame->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kInBackForwardCache);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::COOKIES));
 
   web_contents->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(web_contents));
-  EXPECT_EQ(main_frame, web_contents->GetMainFrame());
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_EQ(main_frame, web_contents->GetPrimaryMainFrame());
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::COOKIES));
 }
 
 IN_PROC_BROWSER_TEST_F(ContentSettingsBackForwardCacheBrowserTest,
@@ -1008,14 +1011,14 @@
       ->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::COOKIES));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), other_url));
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::COOKIES));
 
   // This triggers a OnContentSettingChanged notification that should be
   // processed by the page in the cache.
@@ -1024,9 +1027,9 @@
 
   web_contents->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(web_contents));
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::COOKIES));
 }
 
 // This test verifies that the site settings accurately reflect that an attempt
@@ -1063,9 +1066,9 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_EQ(u"Data URL", web_contents->GetTitle());
 
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
 }
 
 // Tests that if redirect across origins occurs, the new process still gets the
@@ -1089,9 +1092,9 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::COOKIES));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::COOKIES));
 }
 
 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, SendRendererContentRules) {
@@ -1106,17 +1109,17 @@
   HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(
       Profile::FromBrowserContext(web_contents->GetBrowserContext()));
   EXPECT_NE(map, nullptr);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
   map->SetContentSettingDefaultScope(url_2, url_2,
                                      ContentSettingsType::JAVASCRIPT,
                                      ContentSetting::CONTENT_SETTING_BLOCK);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_2));
   base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
 }
 
 IN_PROC_BROWSER_TEST_F(ContentSettingsTest,
@@ -1321,9 +1324,9 @@
   // The import must be blocked.
   ui_test_utils::WaitForViewVisibility(
       browser(), VIEW_ID_CONTENT_SETTING_JAVASCRIPT, true);
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
 }
 
@@ -1506,7 +1509,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
   auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
   ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
 
   {
@@ -1535,7 +1538,7 @@
   prerender_test_helper().NavigatePrimaryPage(prerender_url);
 
   main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
   EXPECT_TRUE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
   EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 1u);
 }
@@ -1551,7 +1554,7 @@
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
 
   auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
   ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
 
   prerender_test_helper().AddPrerender(prerender_url);
@@ -1622,7 +1625,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
   auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
   ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
 
   std::unique_ptr<content::RenderFrameHostWrapper> fenced_frame;
@@ -1630,7 +1633,7 @@
     NonPrimaryPageCookieAccessObserver cookie_observer(GetWebContents());
     fenced_frame = std::make_unique<content::RenderFrameHostWrapper>(
         fenced_frame_test_helper().CreateFencedFrame(
-            GetWebContents()->GetMainFrame(), fenced_frame_url));
+            GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url));
     EXPECT_NE(fenced_frame, nullptr);
     // Ensure notification for cookie access by fenced frame has been sent.
     cookie_observer.Wait();
@@ -1657,7 +1660,7 @@
   EXPECT_EQ(ff_pscs->blocked_local_shared_objects().GetObjectCount(), 1u);
 
   ASSERT_TRUE(
-      content::ExecJs(GetWebContents()->GetMainFrame(),
+      content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                       "const ff = document.querySelector('fencedframe'); "
                       "ff.remove();"));
   ASSERT_TRUE(fenced_frame->WaitUntilRenderFrameDeleted());
@@ -1674,14 +1677,14 @@
       https_server_.GetURL("b.test", "/browsing_data/site_data.html");
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
-  ASSERT_FALSE(GetWebContents()->GetMainFrame()->IsErrorDocument());
+  ASSERT_FALSE(GetWebContents()->GetPrimaryMainFrame()->IsErrorDocument());
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
   auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
 
   content::RenderFrameHost* fenced_frame =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame, nullptr);
   auto* ff_pscs = PageSpecificContentSettings::GetForFrame(fenced_frame);
 
@@ -1728,14 +1731,14 @@
       ContentSettingsType::JAVASCRIPT, ContentSetting::CONTENT_SETTING_BLOCK);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
-  ASSERT_FALSE(GetWebContents()->GetMainFrame()->IsErrorDocument());
+  ASSERT_FALSE(GetWebContents()->GetPrimaryMainFrame()->IsErrorDocument());
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
   auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
 
   content::RenderFrameHost* fenced_frame =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame, nullptr);
   auto* ff_pscs = PageSpecificContentSettings::GetForFrame(fenced_frame);
 
@@ -1751,7 +1754,7 @@
       ContentSettingsType::JAVASCRIPT, ContentSetting::CONTENT_SETTING_ALLOW);
   content::RenderFrameHost* fenced_frame_two =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame_two, nullptr);
   auto* ff_two_pscs =
       PageSpecificContentSettings::GetForFrame(fenced_frame_two);
@@ -1765,7 +1768,7 @@
       ContentSettingsType::JAVASCRIPT, ContentSetting::CONTENT_SETTING_BLOCK);
   content::RenderFrameHost* fenced_frame_three =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame_three, nullptr);
   auto* ff_three_pscs =
       PageSpecificContentSettings::GetForFrame(fenced_frame_three);
@@ -1781,7 +1784,7 @@
       ContentSettingsType::JAVASCRIPT, ContentSetting::CONTENT_SETTING_BLOCK);
   content::RenderFrameHost* fenced_frame_four =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame_four, nullptr);
   auto* ff_four_pscs =
       PageSpecificContentSettings::GetForFrame(fenced_frame_four);
@@ -1796,7 +1799,7 @@
       ContentSettingsType::JAVASCRIPT, ContentSetting::CONTENT_SETTING_DEFAULT);
   content::RenderFrameHost* fenced_frame_five =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(fenced_frame_five, nullptr);
   auto* ff_five_pscs =
       PageSpecificContentSettings::GetForFrame(fenced_frame_five);
@@ -1847,16 +1850,16 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
-  ASSERT_FALSE(web_contents->GetMainFrame()->IsErrorDocument());
+  ASSERT_FALSE(web_contents->GetPrimaryMainFrame()->IsErrorDocument());
   content::RenderFrameHost* fenced_frame =
-      fenced_frame_test_helper().CreateFencedFrame(web_contents->GetMainFrame(),
-                                                   fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_NE(nullptr, fenced_frame);
 
   // The import must be blocked.
   ui_test_utils::WaitForViewVisibility(
       browser(), VIEW_ID_CONTENT_SETTING_JAVASCRIPT, true);
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::JAVASCRIPT));
 }
diff --git a/chrome/browser/content_settings/mixed_content_settings_tab_helper.cc b/chrome/browser/content_settings/mixed_content_settings_tab_helper.cc
index 86aa072..f80c1194 100644
--- a/chrome/browser/content_settings/mixed_content_settings_tab_helper.cc
+++ b/chrome/browser/content_settings/mixed_content_settings_tab_helper.cc
@@ -32,7 +32,7 @@
           WebContents::FromRenderFrameHost(tab->GetOpener()));
   if (opener_settings &&
       opener_settings->IsRunningInsecureContentAllowed(*tab->GetOpener())) {
-    AllowRunningOfInsecureContent(*tab->GetMainFrame());
+    AllowRunningOfInsecureContent(*tab->GetPrimaryMainFrame());
   }
 }
 
diff --git a/chrome/browser/content_settings/mixed_content_settings_tab_helper_browsertest.cc b/chrome/browser/content_settings/mixed_content_settings_tab_helper_browsertest.cc
index 57f1e73..3eadfb7 100644
--- a/chrome/browser/content_settings/mixed_content_settings_tab_helper_browsertest.cc
+++ b/chrome/browser/content_settings/mixed_content_settings_tab_helper_browsertest.cc
@@ -50,7 +50,7 @@
   }
 
   content::RenderFrameHost* current_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   net::EmbeddedTestServer* test_server() { return &ssl_server_; }
@@ -107,7 +107,7 @@
   auto* new_contents_helper =
       MixedContentSettingsTabHelper::FromWebContents(new_contents);
   EXPECT_TRUE(new_contents_helper->IsRunningInsecureContentAllowed(
-      *new_contents->GetMainFrame()));
+      *new_contents->GetPrimaryMainFrame()));
 }
 
 class MixedContentSettingsTabHelperPrerenderBrowserTest
diff --git a/chrome/browser/content_settings/page_specific_content_settings_unittest.cc b/chrome/browser/content_settings/page_specific_content_settings_unittest.cc
index 2f8d0c4e..cf69f3d6 100644
--- a/chrome/browser/content_settings/page_specific_content_settings_unittest.cc
+++ b/chrome/browser/content_settings/page_specific_content_settings_unittest.cc
@@ -50,7 +50,8 @@
 
   task_environment()->FastForwardBy(base::Seconds(1));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
 
   histograms.ExpectTotalCount(kGeolocationHistogramName, 0);
   content_settings->OnContentAllowed(ContentSettingsType::GEOLOCATION);
diff --git a/chrome/browser/content_settings/sound_content_setting_observer.cc b/chrome/browser/content_settings/sound_content_setting_observer.cc
index 9413a47..451365b 100644
--- a/chrome/browser/content_settings/sound_content_setting_observer.cc
+++ b/chrome/browser/content_settings/sound_content_setting_observer.cc
@@ -157,10 +157,10 @@
     // page.
     // TODO(https://crbug.com/1103176): For other types of FrameTrees(fenced
     // frames, portals) than prerendering, we should figure a way of not having
-    // to use GetMainFrame here. (pass the source frame somehow)
+    // to use GetPrimaryMainFrame here. (pass the source frame somehow)
     content_settings::PageSpecificContentSettings* settings =
         content_settings::PageSpecificContentSettings::GetForFrame(
-            web_contents()->GetMainFrame());
+            web_contents()->GetPrimaryMainFrame());
     if (settings)
       settings->OnAudioBlocked();
 
@@ -175,7 +175,7 @@
   logged_site_muted_ukm_ = true;
 
   ukm::builders::Media_SiteMuted(
-      web_contents()->GetMainFrame()->GetPageUkmSourceId())
+      web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId())
       .SetMuteReason(GetSiteMutedReason())
       .Record(ukm::UkmRecorder::Get());
 }
diff --git a/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc b/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
index fc6a399..100a404 100644
--- a/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
+++ b/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
@@ -400,7 +400,7 @@
 
   // Create a fenced frame and wait for the autoplay flag to be set.
   fenced_frame_test_helper().CreateFencedFrameAsync(
-      web_contents()->GetMainFrame(), fenced_frame_url);
+      web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   observer.WaitForFencedFrame();
   observer.GetTestClientForFencedFrame()->AddExpectedOriginAndFlags(
       url::Origin::Create(fenced_frame_url),
diff --git a/chrome/browser/continuous_search/internal/search_result_extractor_producer_unittest.cc b/chrome/browser/continuous_search/internal/search_result_extractor_producer_unittest.cc
index 9681ac9..fb0867b 100644
--- a/chrome/browser/continuous_search/internal/search_result_extractor_producer_unittest.cc
+++ b/chrome/browser/continuous_search/internal/search_result_extractor_producer_unittest.cc
@@ -100,7 +100,7 @@
   // interface.
   void OverrideInterface(FakeSearchResultExtractor* extractor) {
     web_contents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->GetRemoteAssociatedInterfaces()
         ->OverrideBinderForTesting(
             mojom::SearchResultExtractor::Name_,
diff --git a/chrome/browser/crash_recovery_browsertest.cc b/chrome/browser/crash_recovery_browsertest.cc
index 2c8014e..49104aba 100644
--- a/chrome/browser/crash_recovery_browsertest.cc
+++ b/chrome/browser/crash_recovery_browsertest.cc
@@ -115,9 +115,10 @@
   ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                 &title_after_crash));
   EXPECT_NE(title_before_crash, title_after_crash);
-  ASSERT_TRUE(GetActiveWebContents()->GetMainFrame()->GetView()->IsShowing());
+  ASSERT_TRUE(
+      GetActiveWebContents()->GetPrimaryMainFrame()->GetView()->IsShowing());
   ASSERT_FALSE(GetActiveWebContents()
-                   ->GetMainFrame()
+                   ->GetPrimaryMainFrame()
                    ->GetProcess()
                    ->IsProcessBackgrounded());
 }
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc
index 64d9aba..f50251c 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc
@@ -91,9 +91,12 @@
     params.writing_direction_left_to_right = 0;
     params.writing_direction_right_to_left = 0;
 #endif  // BUILDFLAG(IS_MAC)
-    TestRenderViewContextMenu* menu = new TestRenderViewContextMenu(
-        *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        params);
+    TestRenderViewContextMenu* menu =
+        new TestRenderViewContextMenu(*browser()
+                                           ->tab_strip_model()
+                                           ->GetActiveWebContents()
+                                           ->GetPrimaryMainFrame(),
+                                      params);
     menu->Init();
     return menu;
   }
@@ -240,7 +243,10 @@
   // Create a FencedFrame.
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+          browser()
+              ->tab_strip_model()
+              ->GetActiveWebContents()
+              ->GetPrimaryMainFrame(),
           embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   ASSERT_TRUE(fenced_frame_host);
 
diff --git a/chrome/browser/device_api/managed_configuration_service_unittest.cc b/chrome/browser/device_api/managed_configuration_service_unittest.cc
index 8d5a09b7..0d817f7 100644
--- a/chrome/browser/device_api/managed_configuration_service_unittest.cc
+++ b/chrome/browser/device_api/managed_configuration_service_unittest.cc
@@ -33,7 +33,8 @@
     content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents,
                                                                GURL(kUrl));
     ManagedConfigurationServiceImpl::Create(
-        web_contents->GetMainFrame(), remote_.BindNewPipeAndPassReceiver());
+        web_contents->GetPrimaryMainFrame(),
+        remote_.BindNewPipeAndPassReceiver());
   }
 
   TestingProfileManager* profile_manager() { return &profile_manager_; }
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index fdbe4ec..8304ddb 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -1070,7 +1070,8 @@
   //       - data:
   //       - web URL
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* devtools_extension_devtools_page_rfh =
       ChildFrameAt(main_devtools_rfh, 0);
   RenderFrameHost* devtools_extension_panel_rfh =
@@ -1195,7 +1196,8 @@
       CollectAllRenderFrameHosts(main_web_contents());
   EXPECT_EQ(4U, rfhs.size());
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* devtools_extension_devtools_page_rfh =
       ChildFrameAt(main_devtools_rfh, 0);
   RenderFrameHost* devtools_sidebar_pane_extension_rfh =
@@ -1255,7 +1257,8 @@
       CollectAllRenderFrameHosts(main_web_contents());
   EXPECT_EQ(3U, rfhs.size());
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* devtools_extension_devtools_page_rfh =
       ChildFrameAt(main_devtools_rfh, 0);
   RenderFrameHost* http_iframe_rfh =
@@ -1320,7 +1323,8 @@
       CollectAllRenderFrameHosts(main_web_contents());
   EXPECT_EQ(4U, rfhs.size());
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* devtools_extension_devtools_page_rfh =
       ChildFrameAt(main_devtools_rfh, 0);
   RenderFrameHost* devtools_extension_panel_rfh =
@@ -1391,7 +1395,8 @@
       CollectAllRenderFrameHosts(main_web_contents());
   EXPECT_EQ(5U, rfhs.size());
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
 
   RenderFrameHost* devtools_extension_a_devtools_rfh =
       content::FrameMatchingPredicate(
@@ -1471,7 +1476,8 @@
       CollectAllRenderFrameHosts(main_web_contents());
   EXPECT_EQ(4U, rfhs.size());
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* devtools_extension_devtools_page_rfh =
       ChildFrameAt(main_devtools_rfh, 0);
   RenderFrameHost* devtools_extension_panel_rfh =
@@ -1521,7 +1527,8 @@
       "devtoolsFrame.src = '" +
       devtools_url.spec() + "';";
 
-  RenderFrameHost* main_devtools_rfh = main_web_contents()->GetMainFrame();
+  RenderFrameHost* main_devtools_rfh =
+      main_web_contents()->GetPrimaryMainFrame();
 
   content::TestNavigationManager manager(main_web_contents(), devtools_url);
   ASSERT_TRUE(content::ExecuteScript(main_devtools_rfh, javascript));
@@ -1902,7 +1909,7 @@
 
   autofill::ContentAutofillDriver* autofill_driver =
       autofill::ContentAutofillDriverFactory::FromWebContents(GetInspectedTab())
-          ->DriverForFrame(GetInspectedTab()->GetMainFrame());
+          ->DriverForFrame(GetInspectedTab()->GetPrimaryMainFrame());
   auto* autofill_manager = static_cast<autofill::BrowserAutofillManager*>(
       autofill_driver->autofill_manager());
   BrowserAutofillManagerTestDelegateDevtoolsImpl autoFillTestDelegate(
diff --git a/chrome/browser/devtools/devtools_eye_dropper.cc b/chrome/browser/devtools/devtools_eye_dropper.cc
index f052086..fb80dae 100644
--- a/chrome/browser/devtools/devtools_eye_dropper.cc
+++ b/chrome/browser/devtools/devtools_eye_dropper.cc
@@ -37,8 +37,8 @@
     : content::WebContentsObserver(web_contents), callback_(callback) {
   mouse_event_callback_ = base::BindRepeating(
       &DevToolsEyeDropper::HandleMouseEvent, base::Unretained(this));
-  if (web_contents->GetMainFrame()->IsRenderFrameLive())
-    AttachToHost(web_contents->GetMainFrame());
+  if (web_contents->GetPrimaryMainFrame()->IsRenderFrameLive())
+    AttachToHost(web_contents->GetPrimaryMainFrame());
 }
 
 DevToolsEyeDropper::~DevToolsEyeDropper() {
@@ -87,7 +87,7 @@
 void DevToolsEyeDropper::RenderFrameCreated(
     content::RenderFrameHost* frame_host) {
   // Only handle the initial main frame, not speculative ones.
-  if (frame_host != web_contents()->GetMainFrame())
+  if (frame_host != web_contents()->GetPrimaryMainFrame())
     return;
   DCHECK(!host_);
 
@@ -97,7 +97,7 @@
 void DevToolsEyeDropper::RenderFrameDeleted(
     content::RenderFrameHost* frame_host) {
   // Only handle the active main frame, not speculative ones.
-  if (frame_host != web_contents()->GetMainFrame())
+  if (frame_host != web_contents()->GetPrimaryMainFrame())
     return;
   DCHECK(host_);
   DCHECK_EQ(host_, frame_host->GetRenderWidgetHost());
@@ -111,7 +111,7 @@
     content::RenderFrameHost* new_host) {
   // Since we skipped speculative main frames in RenderFrameCreated, we must
   // watch for them being swapped in by watching for RenderFrameHostChanged().
-  if (new_host != web_contents()->GetMainFrame())
+  if (new_host != web_contents()->GetPrimaryMainFrame())
     return;
   // Don't watch for the initial main frame RenderFrameHost, which does not come
   // with a renderer frame. We'll hear about that from RenderFrameCreated.
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index ec8959d..8a67512 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -163,7 +163,7 @@
   content::ChildProcessSecurityPolicy* policy =
       content::ChildProcessSecurityPolicy::GetInstance();
   RenderViewHost* render_view_host =
-      web_contents->GetMainFrame()->GetRenderViewHost();
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
   int renderer_id = render_view_host->GetProcess()->GetID();
   policy->GrantReadFileSystem(renderer_id, file_system.id());
   policy->GrantWriteFileSystem(renderer_id, file_system.id());
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index c702b387..1ffcd9b6 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -899,7 +899,8 @@
     if (allow_web_ui_scheme && target_tab &&
         target_tab->GetLastCommittedURL().scheme() == gurl.scheme()) {
       std::vector<std::string> allowed_webui_hosts;
-      content::RenderFrameHost* frame_host = web_contents()->GetMainFrame();
+      content::RenderFrameHost* frame_host =
+          web_contents()->GetPrimaryMainFrame();
 
       mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote =
           content::CreateWebUIURLLoaderFactory(
@@ -920,7 +921,8 @@
         DevToolsWindow::AsDevToolsWindow(web_contents_)
             ->GetInspectedWebContents();
     if (target_tab) {
-      auto* partition = target_tab->GetMainFrame()->GetStoragePartition();
+      auto* partition =
+          target_tab->GetPrimaryMainFrame()->GetStoragePartition();
       url_loader_factory = partition->GetURLLoaderFactoryForBrowserProcess();
     } else {
       base::DictionaryValue response;
@@ -1537,7 +1539,7 @@
     // process. Grant the devtools process the ability to request URLs from the
     // extension.
     content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestOrigin(
-        web_contents_->GetMainFrame()->GetProcess()->GetID(),
+        web_contents_->GetPrimaryMainFrame()->GetProcess()->GetID(),
         url::Origin::Create(extension->url()));
 
     base::Value::Dict extension_info;
@@ -1657,7 +1659,7 @@
     return;
   // If the client renderer is gone (e.g., the window was closed with both the
   // inspector and client being destroyed), the message can not be sent.
-  if (!web_contents_->GetMainFrame()->IsRenderFrameLive())
+  if (!web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive())
     return;
   base::Value::List arguments;
   if (!arg1.is_none()) {
@@ -1669,7 +1671,7 @@
       }
     }
   }
-  web_contents_->GetMainFrame()->ExecuteJavaScriptMethod(
+  web_contents_->GetPrimaryMainFrame()->ExecuteJavaScriptMethod(
       base::ASCIIToUTF16(object_name), base::ASCIIToUTF16(method_name),
       std::move(arguments), std::move(completion_callback));
 }
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc
index 47e5047..497eab43 100644
--- a/chrome/browser/devtools/devtools_window.cc
+++ b/chrome/browser/devtools/devtools_window.cc
@@ -1509,7 +1509,7 @@
   int child_id = content::ChildProcessHost::kInvalidUniqueID;
   if (inspected_web_contents) {
     content::RenderViewHost* render_view_host =
-        inspected_web_contents->GetMainFrame()->GetRenderViewHost();
+        inspected_web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
     if (render_view_host)
       child_id = render_view_host->GetProcess()->GetID();
   }
diff --git a/chrome/browser/devtools/devtools_window_testing.cc b/chrome/browser/devtools/devtools_window_testing.cc
index 641834a2..17aa223 100644
--- a/chrome/browser/devtools/devtools_window_testing.cc
+++ b/chrome/browser/devtools/devtools_window_testing.cc
@@ -111,7 +111,7 @@
   }
   std::u16string harness = base::UTF8ToUTF16(
       content::DevToolsFrontendHost::GetFrontendResource(kHarnessScript));
-  window->main_web_contents_->GetMainFrame()->ExecuteJavaScript(
+  window->main_web_contents_->GetPrimaryMainFrame()->ExecuteJavaScript(
       harness, base::NullCallback());
 }
 
diff --git a/chrome/browser/devtools/protocol/cast_handler.cc b/chrome/browser/devtools/protocol/cast_handler.cc
index 116bf43..0065b9a 100644
--- a/chrome/browser/devtools/protocol/cast_handler.cc
+++ b/chrome/browser/devtools/protocol/cast_handler.cc
@@ -269,7 +269,7 @@
 
   if (presentation_url.isJust()) {
     url::Origin frame_origin =
-        web_contents_->GetMainFrame()->GetLastCommittedOrigin();
+        web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin();
     std::vector<media_router::MediaSource> sources = {
         media_router::MediaSource(presentation_url.fromJust())};
     query_result_manager_->SetSourcesForCastMode(
diff --git a/chrome/browser/devtools/protocol/page_handler.cc b/chrome/browser/devtools/protocol/page_handler.cc
index 2a5c9aa..9700c40 100644
--- a/chrome/browser/devtools/protocol/page_handler.cc
+++ b/chrome/browser/devtools/protocol/page_handler.cc
@@ -195,7 +195,7 @@
 
   absl::variant<printing::mojom::PrintPagesParamsPtr, std::string>
       print_pages_params = print_to_pdf::GetPrintPagesParams(
-          web_contents_->GetMainFrame()->GetLastCommittedURL(),
+          web_contents_->GetPrimaryMainFrame()->GetLastCommittedURL(),
           OptionalFromMaybe<bool>(landscape),
           OptionalFromMaybe<bool>(display_header_footer),
           OptionalFromMaybe<bool>(print_background),
@@ -225,7 +225,7 @@
   if (auto* print_manager =
           print_to_pdf::PdfPrintManager::FromWebContents(web_contents_.get())) {
     print_manager->PrintToPdf(
-        web_contents_->GetMainFrame(), page_ranges.fromMaybe(""),
+        web_contents_->GetPrimaryMainFrame(), page_ranges.fromMaybe(""),
         std::move(absl::get<printing::mojom::PrintPagesParamsPtr>(
             print_pages_params)),
         base::BindOnce(&PageHandler::OnPDFCreated,
diff --git a/chrome/browser/dips/dips_helper_browsertest.cc b/chrome/browser/dips/dips_helper_browsertest.cc
index 19096497..36e86f8 100644
--- a/chrome/browser/dips/dips_helper_browsertest.cc
+++ b/chrome/browser/dips/dips_helper_browsertest.cc
@@ -203,13 +203,14 @@
   // Navigating to this URL sets a cookie.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   // Wait until we can click.
-  content::WaitForHitTestData(web_contents->GetMainFrame());
+  content::WaitForHitTestData(web_contents->GetPrimaryMainFrame());
 
   histograms.ExpectTotalCount(kTimeToInteraction, 0);
   histograms.ExpectTotalCount(kTimeToStorage, 0);
 
   SetDIPSTime(time + base::Seconds(10));
-  UserActivationObserver observer(web_contents, web_contents->GetMainFrame());
+  UserActivationObserver observer(web_contents,
+                                  web_contents->GetPrimaryMainFrame());
   SimulateMouseClick(web_contents, 0, blink::WebMouseEvent::Button::kLeft);
   observer.Wait();
 
@@ -231,14 +232,15 @@
   // Navigating to this URL sets a cookie.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, url));
   // Wait until we can click.
-  content::WaitForHitTestData(web_contents->GetMainFrame());
+  content::WaitForHitTestData(web_contents->GetPrimaryMainFrame());
 
   histograms.ExpectTotalCount(kTimeToInteraction, 0);
   histograms.ExpectTotalCount(kTimeToInteraction_OTR_Block3PC, 0);
   histograms.ExpectTotalCount(kTimeToStorage, 0);
 
   SetDIPSTime(time + base::Seconds(10));
-  UserActivationObserver observer(web_contents, web_contents->GetMainFrame());
+  UserActivationObserver observer(web_contents,
+                                  web_contents->GetPrimaryMainFrame());
   SimulateMouseClick(web_contents, 0, blink::WebMouseEvent::Button::kLeft);
   observer.Wait();
 
@@ -257,7 +259,7 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("a.test", "/title1.html")));
-  content::RenderFrameHost* frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame = web_contents->GetPrimaryMainFrame();
   content::WaitForHitTestData(frame);  // wait until we can click.
   SetDIPSTime(time);
   UserActivationObserver click_observer(web_contents, frame);
diff --git a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
index 5e0aab2..b83295b1 100644
--- a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
+++ b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
@@ -217,7 +217,7 @@
   ASSERT_TRUE(contents_after_nav != NULL);
   EXPECT_EQ(url, contents_after_nav->GetLastCommittedURL());
   content::RenderFrameHost* render_frame_host =
-      contents_after_nav->GetMainFrame();
+      contents_after_nav->GetPrimaryMainFrame();
   EXPECT_EQ(0, render_frame_host->GetEnabledBindings());
   EXPECT_EQ(expected_mime_type, contents_after_nav->GetContentsMimeType());
 }
diff --git a/chrome/browser/dom_distiller/tab_utils.cc b/chrome/browser/dom_distiller/tab_utils.cc
index 667f65a..70d656d 100644
--- a/chrome/browser/dom_distiller/tab_utils.cc
+++ b/chrome/browser/dom_distiller/tab_utils.cc
@@ -125,7 +125,7 @@
   // be cancelled and would not be restarted when the page is restored from the
   // cache.
   content::BackForwardCache::DisableForRenderFrameHost(
-      source_page_handle->web_contents()->GetMainFrame(),
+      source_page_handle->web_contents()->GetPrimaryMainFrame(),
       back_forward_cache::DisabledReason(
           back_forward_cache::DisabledReasonId::
               kDomDistiller_SelfDeletingRequestDelegate));
diff --git a/chrome/browser/dom_distiller/tab_utils_browsertest.cc b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
index c54e127..aa89e60b 100644
--- a/chrome/browser/dom_distiller/tab_utils_browsertest.cc
+++ b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
@@ -157,14 +157,14 @@
   const GURL& article_url() const { return article_url_; }
 
   std::string GetDocumentTitle(content::WebContents* web_contents) const {
-    return content::ExecuteScriptAndGetValue(web_contents->GetMainFrame(),
-                                             "document.title")
+    return content::ExecuteScriptAndGetValue(
+               web_contents->GetPrimaryMainFrame(), "document.title")
         .GetString();
   }
 
   std::string GetArticleHeading(content::WebContents* web_contents) const {
     return content::ExecuteScriptAndGetValue(
-               web_contents->GetMainFrame(),
+               web_contents->GetPrimaryMainFrame(),
                "document.getElementById('title-holder').textContent")
         .GetString();
   }
@@ -331,8 +331,10 @@
   GURL url1(article_url());
   content::WebContents* initial_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   int process_id = main_frame->GetProcess()->GetID();
   int frame_routing_id = main_frame->GetRoutingID();
   GURL url2(https_server_->GetURL("/title1.html"));
@@ -497,7 +499,7 @@
   const GURL fenced_frame_url =
       https_server_->GetURL("/fenced_frames/title1.html");
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      source_web_contents()->GetMainFrame(), fenced_frame_url));
+      source_web_contents()->GetPrimaryMainFrame(), fenced_frame_url));
 
   // Ensure that the navigation in the fenced frame doesn't affect the
   // SelfDeletingRequestDelegate.
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 1455ffaa..cf9d4e03 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -1876,7 +1876,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), kFencedFrameUrl);
+          GetWebContents()->GetPrimaryMainFrame(), kFencedFrameUrl);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   // Check that the tab download state wasn't reset by the  navigation on the
@@ -2966,7 +2966,7 @@
       blink::mojom::ContextMenuDataMediaType::kPlugin;
   context_menu_params.src_url = url;
   context_menu_params.page_url = inner_web_contents->GetLastCommittedURL();
-  TestRenderViewContextMenu menu(*inner_web_contents->GetMainFrame(),
+  TestRenderViewContextMenu menu(*inner_web_contents->GetPrimaryMainFrame(),
                                  context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_SAVE_PAGE, 0);
@@ -3124,10 +3124,10 @@
       blink::mojom::ContextMenuDataMediaType::kImage;
   context_menu_params.src_url = subframe_url;
   context_menu_params.page_url =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0)
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0)
           ->GetLastCommittedURL();
   content::RenderFrameHost* frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(frame);
   TestRenderViewContextMenu menu(*frame, context_menu_params);
   menu.Init();
@@ -3215,7 +3215,7 @@
       blink::mojom::ContextMenuDataMediaType::kPlugin;
   context_menu_params.src_url = subframe_url;
   context_menu_params.page_url = inner_web_contents->GetLastCommittedURL();
-  TestRenderViewContextMenu menu(*inner_web_contents->GetMainFrame(),
+  TestRenderViewContextMenu menu(*inner_web_contents->GetPrimaryMainFrame(),
                                  context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEAVAS, 0);
@@ -3303,9 +3303,11 @@
       blink::mojom::ContextMenuDataMediaType::kImage;
   context_menu_params.src_url = url;
   context_menu_params.page_url = url;
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
   waiter_context_menu->WaitForFinished();
@@ -3376,9 +3378,11 @@
       blink::mojom::ContextMenuDataMediaType::kImage;
   context_menu_params.src_url = GURL(data_url);
   context_menu_params.page_url = url;
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
   waiter_context_menu->WaitForFinished();
@@ -3440,7 +3444,8 @@
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(web_contents);
-  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* render_frame_host =
+      web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(render_frame_host);
   content::TestNavigationObserver navigation_observer(web_contents, 1);
   EXPECT_TRUE(content::ExecJs(render_frame_host, "SubmitForm()"));
@@ -3477,7 +3482,7 @@
       blink::mojom::ContextMenuDataMediaType::kImage;
   context_menu_params.src_url = jpeg_url;
   context_menu_params.page_url = jpeg_url;
-  TestRenderViewContextMenu menu(*web_contents->GetMainFrame(),
+  TestRenderViewContextMenu menu(*web_contents->GetPrimaryMainFrame(),
                                  context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
@@ -3789,11 +3794,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   waiter->WaitForFinished();
   EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
@@ -3874,11 +3883,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kRight;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   waiter->WaitForFinished();
   EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
@@ -3969,11 +3982,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kRight;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   download_waiter->WaitForFinished();
   EXPECT_EQ(1u,
@@ -4032,9 +4049,11 @@
       blink::mojom::ContextMenuDataMediaType::kImage;
   context_menu_params.page_url = url;
   context_menu_params.src_url = img_url;
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
   waiter_context_menu->WaitForFinished();
@@ -4117,11 +4136,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   waiter->WaitForFinished();
   EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
@@ -4779,7 +4802,8 @@
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(web_contents);
-  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* render_frame_host =
+      web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(render_frame_host);
 
   // Clicking the <a download> in the iframe should navigate the iframe,
@@ -5072,11 +5096,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kRight;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   waiter->WaitForFinished();
   EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
   CheckDownloadStates(1, DownloadItem::COMPLETE);
@@ -5125,11 +5153,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kRight;
   mouse_event.SetPositionInWidget(15, 15);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   waiter->WaitForFinished();
   std::string accept_header;
   headers.GetHeader(net::HttpRequestHeaders::kAccept, &accept_header);
diff --git a/chrome/browser/download/download_frame_policy_browsertest.cc b/chrome/browser/download/download_frame_policy_browsertest.cc
index f74c721..1a74b72 100644
--- a/chrome/browser/download/download_frame_policy_browsertest.cc
+++ b/chrome/browser/download/download_frame_policy_browsertest.cc
@@ -197,7 +197,7 @@
     }
 
     content::TestNavigationObserver navigation_observer(web_contents());
-    EXPECT_TRUE(content::ExecJs(web_contents()->GetMainFrame(), script,
+    EXPECT_TRUE(content::ExecJs(web_contents()->GetPrimaryMainFrame(), script,
                                 content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
     navigation_observer.Wait();
@@ -650,7 +650,7 @@
                              is_cross_origin);
 
   EXPECT_TRUE(
-      ExecJs(web_contents()->GetMainFrame(),
+      ExecJs(web_contents()->GetPrimaryMainFrame(),
              content::JsReplace("document.querySelector('iframe').sandbox = $1",
                                 update_to_token)));
 
@@ -658,7 +658,7 @@
   content::TestNavigationManager navigation_observer(web_contents(),
                                                      download_url);
   EXPECT_TRUE(
-      ExecJs(web_contents()->GetMainFrame(),
+      ExecJs(web_contents()->GetPrimaryMainFrame(),
              content::JsReplace("document.querySelector('iframe').src = $1",
                                 download_url)));
   navigation_observer.WaitForNavigationFinished();
@@ -693,7 +693,7 @@
                              is_cross_origin);
 
   EXPECT_TRUE(
-      ExecJs(web_contents()->GetMainFrame(),
+      ExecJs(web_contents()->GetPrimaryMainFrame(),
              content::JsReplace("document.querySelector('iframe').sandbox = $1",
                                 update_to_token)));
 
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index fcfa808..ad150eb 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -216,7 +216,7 @@
     // so we use the primary main RenderFrameHost here, to avoid discarding the
     // request in the case that the initiator RFH is already gone.
     permission_request_manager->AddRequest(
-        web_contents_->GetMainFrame(),
+        web_contents_->GetPrimaryMainFrame(),
         new DownloadPermissionRequest(factory_.GetWeakPtr(), request_origin));
   } else {
     // Call CancelOnce() so we don't set the content settings.
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc
index 52b7fe0..23098c0 100644
--- a/chrome/browser/download/download_request_limiter_unittest.cc
+++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -358,7 +358,7 @@
 
   // Set up a renderer-initiated navigation to the same host.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foo.com/bar2"), web_contents()->GetMainFrame());
+      GURL("http://foo.com/bar2"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
 
   // The state should not be reset.
@@ -369,7 +369,7 @@
 
   // Renderer-initiated nav to a different host shouldn't reset the state.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://fooey.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://fooey.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -378,7 +378,8 @@
 
   // Set up a subframe. Navigations in the subframe shouldn't reset the state.
   content::RenderFrameHostTester* rfh_tester =
-      content::RenderFrameHostTester::For(web_contents()->GetMainFrame());
+      content::RenderFrameHostTester::For(
+          web_contents()->GetPrimaryMainFrame());
   content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe");
   subframe = content::NavigationSimulator::NavigateAndCommitFromDocument(
       GURL("http://foo.com"), subframe);
@@ -407,7 +408,7 @@
   // same host or a different host, in either the main frame or the subframe.
   // The UI state goes to DEFAULT until an actual download is triggered.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://fooey.com/bar2"), web_contents()->GetMainFrame());
+      GURL("http://fooey.com/bar2"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -415,15 +416,15 @@
             download_request_limiter_->GetDownloadUiStatus(web_contents()));
 
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foo.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://foo.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
             download_request_limiter_->GetDownloadStatus(web_contents()));
   EXPECT_EQ(DownloadRequestLimiter::DOWNLOAD_UI_DEFAULT,
             download_request_limiter_->GetDownloadUiStatus(web_contents()));
 
-  rfh_tester =
-      content::RenderFrameHostTester::For(web_contents()->GetMainFrame());
+  rfh_tester = content::RenderFrameHostTester::For(
+      web_contents()->GetPrimaryMainFrame());
   subframe = rfh_tester->AppendChild("subframe");
   subframe = content::NavigationSimulator::NavigateAndCommitFromDocument(
       GURL("http://foo.com"), subframe);
@@ -469,7 +470,7 @@
   // The state should not be reset on a pending renderer-initiated load to
   // the same host.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foobar.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://foobar.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -477,8 +478,8 @@
             download_request_limiter_->GetDownloadUiStatus(web_contents()));
 
   // The state should not be reset for a subframe nav to the same host.
-  rfh_tester =
-      content::RenderFrameHostTester::For(web_contents()->GetMainFrame());
+  rfh_tester = content::RenderFrameHostTester::For(
+      web_contents()->GetPrimaryMainFrame());
   subframe = rfh_tester->AppendChild("subframe");
   subframe = content::NavigationSimulator::NavigateAndCommitFromDocument(
       GURL("http://foobar.com/bar"), subframe);
@@ -497,7 +498,7 @@
   // Even a pending load to a different host in the main frame should not
   // reset the state.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foo.com"), web_contents()->GetMainFrame());
+      GURL("http://foo.com"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -525,7 +526,7 @@
   // Renderer-initiated navigation to a different host shouldn't reset the
   // state.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foobar.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://foobar.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -587,7 +588,7 @@
   // Renderer-initiated navigation to a different host shouldn't reset the
   // state.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foobar.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://foobar.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
             download_request_limiter_->GetDownloadStatus(web_contents()));
@@ -808,7 +809,7 @@
 
   // Renderer initiated reload will not reset download status.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("http://foo.com/bar"), web_contents()->GetMainFrame());
+      GURL("http://foo.com/bar"), web_contents()->GetPrimaryMainFrame());
   LoadCompleted();
   EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
             download_request_limiter_->GetDownloadStatus(web_contents()));
diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc
index 9e7e588d..d2771460 100644
--- a/chrome/browser/download/download_target_determiner.cc
+++ b/chrome/browser/download/download_target_determiner.cc
@@ -744,7 +744,8 @@
   content::WebContents* web_contents =
       content::DownloadItemUtils::GetWebContents(download_);
   if (web_contents)
-    render_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+    render_process_id =
+        web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
   IsHandledBySafePlugin(
       render_process_id, net::FilePathToFileURL(local_path_), mime_type_,
       RETRY_IF_STALE_PLUGIN_LIST,
diff --git a/chrome/browser/download/mixed_content_download_blocking.cc b/chrome/browser/download/mixed_content_download_blocking.cc
index b0d255c3..3dbda34 100644
--- a/chrome/browser/download/mixed_content_download_blocking.cc
+++ b/chrome/browser/download/mixed_content_download_blocking.cc
@@ -310,7 +310,7 @@
     return;
   }
 
-  web_contents->GetMainFrame()->AddMessageToConsole(
+  web_contents->GetPrimaryMainFrame()->AddMessageToConsole(
       blink::mojom::ConsoleMessageLevel::kError,
       base::StringPrintf(
           "Mixed Content: The site at '%s' was loaded over a secure "
diff --git a/chrome/browser/download/save_package_file_picker.cc b/chrome/browser/download/save_package_file_picker.cc
index 1df01bf..1a8a1a74 100644
--- a/chrome/browser/download/save_package_file_picker.cc
+++ b/chrome/browser/download/save_package_file_picker.cc
@@ -148,7 +148,8 @@
     bool can_save_as_complete,
     DownloadPrefs* download_prefs,
     content::SavePackagePathPickedCallback callback)
-    : render_process_id_(web_contents->GetMainFrame()->GetProcess()->GetID()),
+    : render_process_id_(
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID()),
       can_save_as_complete_(can_save_as_complete),
       download_prefs_(download_prefs),
       callback_(std::move(callback)) {
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index c6ef35b..85b7ef5d5 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -1162,23 +1162,25 @@
   // Kill one of renderer processes (this is the essence of this test).
   WebContents* web_contents = GetCurrentTab(browser());
   bool did_kill_a_process = false;
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      [](WebContents* web_contents, bool* did_kill_a_process,
-         RenderFrameHost* frame) {
-        if (frame->GetLastCommittedURL().host() == "bar.com") {
-          RenderProcessHost* process_to_kill = frame->GetProcess();
-          EXPECT_NE(web_contents->GetMainFrame()->GetProcess()->GetID(),
-                    process_to_kill->GetID())
-              << "a.com and bar.com should be in different processes.";
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(
+          [](WebContents* web_contents, bool* did_kill_a_process,
+             RenderFrameHost* frame) {
+            if (frame->GetLastCommittedURL().host() == "bar.com") {
+              RenderProcessHost* process_to_kill = frame->GetProcess();
+              EXPECT_NE(
+                  web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+                  process_to_kill->GetID())
+                  << "a.com and bar.com should be in different processes.";
 
-          EXPECT_TRUE(process_to_kill->FastShutdownIfPossible());
-          EXPECT_FALSE(process_to_kill->IsInitializedAndNotDead());
-          *did_kill_a_process = true;
-          return content::RenderFrameHost::FrameIterationAction::kStop;
-        }
-        return content::RenderFrameHost::FrameIterationAction::kContinue;
-      },
-      web_contents, &did_kill_a_process));
+              EXPECT_TRUE(process_to_kill->FastShutdownIfPossible());
+              EXPECT_FALSE(process_to_kill->IsInitializedAndNotDead());
+              *did_kill_a_process = true;
+              return content::RenderFrameHost::FrameIterationAction::kStop;
+            }
+            return content::RenderFrameHost::FrameIterationAction::kContinue;
+          },
+          web_contents, &did_kill_a_process));
   EXPECT_TRUE(did_kill_a_process);
 
   // Main verification is that we don't hang and time out when saving.
@@ -1244,7 +1246,7 @@
 
     if (GetParam() == content::SAVE_PAGE_TYPE_AS_MHTML) {
       std::set<url::Origin> origins;
-      GetCurrentTab(browser())->GetMainFrame()->ForEachRenderFrameHost(
+      GetCurrentTab(browser())->GetPrimaryMainFrame()->ForEachRenderFrameHost(
           base::BindRepeating(&CheckFrameForMHTML, base::Unretained(&origins)));
       int unique_origins = origins.size();
       EXPECT_EQ(expected_number_of_frames_in_saved_page, unique_origins)
@@ -1328,7 +1330,7 @@
           save_page_type == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
         DLOG(INFO) << "Verifying that a.htm frame has fully loaded...";
         std::vector<std::string> frame_names;
-        GetCurrentTab(browser())->GetMainFrame()->ForEachRenderFrameHost(
+        GetCurrentTab(browser())->GetPrimaryMainFrame()->ForEachRenderFrameHost(
             base::BindRepeating(
                 [](std::vector<std::string>* frame_names,
                    content::RenderFrameHost* frame) {
diff --git a/chrome/browser/engagement/site_engagement_helper_browsertest.cc b/chrome/browser/engagement/site_engagement_helper_browsertest.cc
index eb3caa59..d2d9d8f 100644
--- a/chrome/browser/engagement/site_engagement_helper_browsertest.cc
+++ b/chrome/browser/engagement/site_engagement_helper_browsertest.cc
@@ -233,7 +233,7 @@
   EXPECT_TRUE(host_observer.was_activated());
 
   EXPECT_TRUE(
-      content::ExecJs(web_contents()->GetMainFrame(), "attemptPlay();"));
+      content::ExecJs(web_contents()->GetPrimaryMainFrame(), "attemptPlay();"));
 
   tester.WaitForEngagementEvent(EngagementType::kMediaVisible);
   EXPECT_EQ(tester.last_updated_type(), EngagementType::kMediaVisible);
diff --git a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc
index dde1e1a..a9a997d 100644
--- a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc
@@ -91,7 +91,7 @@
 
   content::WebContents* web_contents() const { return web_contents_.get(); }
   content::RenderFrameHost* main_frame() const {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
  protected:
diff --git a/chrome/browser/enterprise/connectors/file_system/browsertest_helper.cc b/chrome/browser/enterprise/connectors/file_system/browsertest_helper.cc
index fe3311f..0d3cccb 100644
--- a/chrome/browser/enterprise/connectors/file_system/browsertest_helper.cc
+++ b/chrome/browser/enterprise/connectors/file_system/browsertest_helper.cc
@@ -176,7 +176,7 @@
       window.domAutomationController.send(
           document.getElementById('login').value);
     )";
-  return ExecuteScriptAndExtractString(web_contents()->GetMainFrame(),
+  return ExecuteScriptAndExtractString(web_contents()->GetPrimaryMainFrame(),
                                        get_login_value, result);
 }
 
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc
index 9c3d461..78574ca 100644
--- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc
+++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc
@@ -20,7 +20,6 @@
 #include "components/enterprise/browser/reporting/report_scheduler.h"
 #include "components/policy/core/common/cloud/dm_token.h"
 #include "components/prefs/pref_service.h"
-#include "components/reporting/client/report_queue_provider.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace em = enterprise_management;
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index 09d9c77..4cd2e60 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -163,7 +163,7 @@
   const PermissionsData* permissions_data = extension->permissions_data();
 
   const GURL& url =
-      web_contents()->GetMainFrame()->GetLastCommittedOrigin().GetURL();
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin().GetURL();
 
   // If the extension requested the host permission to |url| but had it
   // withheld, we grant it active tab-style permissions, even if it doesn't have
@@ -215,7 +215,7 @@
       ProcessManager* process_manager = ProcessManager::Get(browser_context);
       SendRendererMessageToProcesses(
           process_manager->GetRenderFrameHostsForExtension(extension->id()),
-          web_contents()->GetMainFrame()->GetProcess(), update_message);
+          web_contents()->GetPrimaryMainFrame()->GetProcess(), update_message);
 
       // If more things ever need to know about this, we should consider making
       // an observer class.
@@ -284,7 +284,8 @@
   RendererMessageFunction clear_message =
       base::BindRepeating(&ClearTabSpecificPermissions, extension_ids, tab_id_);
   SendRendererMessageToProcesses(
-      frame_hosts, web_contents()->GetMainFrame()->GetProcess(), clear_message);
+      frame_hosts, web_contents()->GetPrimaryMainFrame()->GetProcess(),
+      clear_message);
 
   granted_extensions_.Clear();
 }
diff --git a/chrome/browser/extensions/alert_apitest.cc b/chrome/browser/extensions/alert_apitest.cc
index 8467b95..5d561561 100644
--- a/chrome/browser/extensions/alert_apitest.cc
+++ b/chrome/browser/extensions/alert_apitest.cc
@@ -78,7 +78,7 @@
   ExtensionHost* host = ProcessManager::Get(browser()->profile())
                             ->GetBackgroundHostForExtension(extension->id());
   ASSERT_TRUE(host);
-  host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+  host->host_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"alert('This should not crash.');", base::NullCallback());
 
   ASSERT_NO_FATAL_FAILURE(CloseDialog());
@@ -97,7 +97,7 @@
   size_t call_count = 0;
   for (size_t i = 0; i != num_dialogs; ++i) {
     const std::string dialog_name = "Dialog #" + base::NumberToString(i) + ".";
-    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    host->host_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"alert('" + base::ASCIIToUTF16(dialog_name) + u"');",
         base::BindOnce(&CheckAlertResult, dialog_name,
                        base::Unretained(&call_count)));
@@ -133,7 +133,7 @@
   for (size_t i = 0; i != num_accepted_dialogs; ++i) {
     const std::string dialog_name =
         "Accepted dialog #" + base::NumberToString(i) + ".";
-    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    host->host_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"confirm('" + base::ASCIIToUTF16(dialog_name) + u"');",
         base::BindOnce(&CheckConfirmResult, dialog_name, true,
                        base::Unretained(&call_count)));
@@ -141,7 +141,7 @@
   for (size_t i = 0; i != num_cancelled_dialogs; ++i) {
     const std::string dialog_name =
         "Cancelled dialog #" + base::NumberToString(i) + ".";
-    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    host->host_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"confirm('" + base::ASCIIToUTF16(dialog_name) + u"');",
         base::BindOnce(&CheckConfirmResult, dialog_name, false,
                        base::Unretained(&call_count)));
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
index 0349f506..dad6385 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -148,7 +148,7 @@
   }
   autofill::ContentAutofillDriver* autofill_driver =
       autofill::ContentAutofillDriverFactory::FromWebContents(web_contents)
-          ->DriverForFrame(web_contents->GetMainFrame());
+          ->DriverForFrame(web_contents->GetPrimaryMainFrame());
   if (!autofill_driver)
     return nullptr;
   return autofill_driver->autofill_manager();
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
index 24ae16f..a17bf5a 100644
--- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
+++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
@@ -166,7 +166,7 @@
 std::string GetPageTextContent(content::WebContents* web_contents) {
   std::string text_content;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       "domAutomationController.send(document.body.textContent);",
       &text_content));
   return text_content;
@@ -353,7 +353,7 @@
   }
 
   content::RenderFrameHost* GetExtensionMainFrame() const {
-    return extension_contents_->GetMainFrame();
+    return extension_contents_->GetPrimaryMainFrame();
   }
 
   void ExecuteJavascript(const std::string& function) const {
diff --git a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc
index 670b576c..e15e657 100644
--- a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc
+++ b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc
@@ -139,8 +139,10 @@
   // Sets up the top-level model, which is the list of menu items (both related
   // and unrelated to extensions) that is passed to UI code to be displayed.
   bool SetupTopLevelMenuModel() {
-    content::RenderFrameHost* frame =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* frame = browser()
+                                          ->tab_strip_model()
+                                          ->GetActiveWebContents()
+                                          ->GetPrimaryMainFrame();
     content::ContextMenuParams params;
     params.page_url = frame->GetLastCommittedURL();
 
diff --git a/chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc b/chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc
index 92d6d7bb..c226e5bf 100644
--- a/chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc
+++ b/chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc
@@ -889,7 +889,7 @@
   // Click on a menu item in the main frame.
   EXPECT_EQ(
       "pageUrl=" + url_with_frame.spec() + ", frameUrl=undefined, frameId=0",
-      ClickMenuInFrame(GetWebContents()->GetMainFrame(), "item1"));
+      ClickMenuInFrame(GetWebContents()->GetPrimaryMainFrame(), "item1"));
 
   // Click on a menu item in the child frame.
   content::RenderFrameHost* child_frame = content::FrameMatchingPredicate(
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc
index d9dc35e..a07c8a9 100644
--- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc
+++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc
@@ -90,7 +90,7 @@
     error_report.window_type = GetWindowType(web_contents);
 
     base::TimeTicks render_process_start_time =
-        web_contents->GetMainFrame()->GetProcess()->GetLastInitTime();
+        web_contents->GetPrimaryMainFrame()->GetProcess()->GetLastInitTime();
     base::TimeDelta render_process_uptime;
     if (!render_process_start_time.is_null()) {
       render_process_uptime =
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc
index 6942ced..969f24f 100644
--- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc
+++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc
@@ -259,9 +259,10 @@
 
   // The created AttestationPermissionRequest deletes itself once complete.
   permission_request_manager->AddRequest(
-      web_contents->GetMainFrame(),  // Extension API targets a particular tab,
-                                     // so select the current main frame to
-                                     // handle the request.
+      web_contents
+          ->GetPrimaryMainFrame(),  // Extension API targets a particular tab,
+                                    // so select the current main frame to
+                                    // handle the request.
       NewAttestationPermissionRequest(
           origin,
           base::BindOnce(
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc
index 38a5a8d..003d8a4 100644
--- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc
+++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc
@@ -103,7 +103,7 @@
                                         : browser()
                                               ->tab_strip_model()
                                               ->GetActiveWebContents()
-                                              ->GetMainFrame();
+                                              ->GetPrimaryMainFrame();
   }
 
   void ExpectChromeRuntimeIsUndefined() {
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index 8cca5e4..1233c0a 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -211,7 +211,7 @@
   }
   // This is *not* redundant to the checks below, as
   // web_contents.GetLastCommittedURL() may be different from
-  // web_contents.GetMainFrame()->GetLastCommittedURL(), with the
+  // web_contents.GetPrimaryMainFrame()->GetLastCommittedURL(), with the
   // former being a 'virtual' URL as obtained from NavigationEntry.
   if (!ExtensionMayAttachToURL(extension, extension_profile,
                                web_contents.GetLastCommittedURL(), error)) {
@@ -219,7 +219,7 @@
   }
 
   return ExtensionMayAttachToRenderFrameHost(
-      extension, extension_profile, web_contents.GetMainFrame(), error);
+      extension, extension_profile, web_contents.GetPrimaryMainFrame(), error);
 }
 
 bool ExtensionMayAttachToAgentHost(const Extension& extension,
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
index 447a9a56..653f90b 100644
--- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -280,7 +280,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   std::unique_ptr<content::MockNavigationHandle> navigation_handle =
       std::make_unique<content::MockNavigationHandle>(
-          GURL("https://google.com/"), web_contents->GetMainFrame());
+          GURL("https://google.com/"), web_contents->GetPrimaryMainFrame());
   navigation_handle->set_has_committed(true);
   navigation_handle->set_is_same_document(false);
   EXPECT_TRUE(RunAttachFunction(web_contents, ""));
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc
index fb24064..3908dc3 100644
--- a/chrome/browser/extensions/api/declarative_content/content_action.cc
+++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -370,11 +370,12 @@
     content::WebContents* contents,
     const Extension* extension) const {
   ContentScriptTracker::WillExecuteCode(base::PassKey<RequestContentScript>(),
-                                        contents->GetMainFrame(), *extension);
+                                        contents->GetPrimaryMainFrame(),
+                                        *extension);
 
   mojom::LocalFrame* local_frame =
       ExtensionWebContentsObserver::GetForWebContents(contents)->GetLocalFrame(
-          contents->GetMainFrame());
+          contents->GetPrimaryMainFrame());
   if (!local_frame) {
     // TODO(https://crbug.com/1203579): Need to review when this method is
     // called with non-live frame.
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_condition_tracker_test.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_condition_tracker_test.cc
index b1d1b09..2f178e0f 100644
--- a/chrome/browser/extensions/api/declarative_content/declarative_content_condition_tracker_test.cc
+++ b/chrome/browser/extensions/api/declarative_content/declarative_content_condition_tracker_test.cc
@@ -28,7 +28,7 @@
 DeclarativeContentConditionTrackerTest::MakeTab() {
   std::unique_ptr<content::WebContents> tab(
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr));
-  content::RenderFrameHostTester::For(tab->GetMainFrame())
+  content::RenderFrameHostTester::For(tab->GetPrimaryMainFrame())
       ->InitializeRenderFrameIfNeeded();
   return tab;
 }
@@ -37,7 +37,7 @@
 DeclarativeContentConditionTrackerTest::GetMockRenderProcessHost(
     content::WebContents* contents) {
   return static_cast<content::MockRenderProcessHost*>(
-      contents->GetMainFrame()->GetProcess());
+      contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 TestingProfile::TestingFactories
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index b9467604..0264870 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -267,12 +267,12 @@
 
   content::WebContents* web_contents() const { return web_contents(browser()); }
 
-  content::RenderFrameHost* GetMainFrame(Browser* browser) const {
-    return web_contents(browser)->GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame(Browser* browser) const {
+    return web_contents(browser)->GetPrimaryMainFrame();
   }
 
-  content::RenderFrameHost* GetMainFrame() const {
-    return GetMainFrame(browser());
+  content::RenderFrameHost* GetPrimaryMainFrame() const {
+    return GetPrimaryMainFrame(browser());
   }
 
   content::RenderFrameHost* GetFrameByName(const std::string& name) const {
@@ -370,7 +370,7 @@
   // Returns true if the navigation to given |url| is blocked.
   bool IsNavigationBlocked(const GURL& url) {
     EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    return !WasFrameWithScriptLoaded(GetMainFrame());
+    return !WasFrameWithScriptLoaded(GetPrimaryMainFrame());
   }
 
   void VerifyNavigations(const std::vector<GURL>& expected_blocked_urls,
@@ -463,7 +463,7 @@
     const char* referrer_policy = use_frame_referrer ? "origin" : "no-referrer";
 
     ASSERT_TRUE(content::ExecuteScript(
-        GetMainFrame(),
+        GetPrimaryMainFrame(),
         base::StringPrintf(R"(
           document.getElementsByName('%s')[0].referrerPolicy = '%s';
           document.getElementsByName('%s')[0].src = '%s';)",
@@ -938,7 +938,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_EQ(test_case.expect_main_frame_loaded,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     content::PageType expected_page_type = test_case.expect_main_frame_loaded
                                                ? content::PAGE_TYPE_NORMAL
@@ -979,7 +979,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_EQ(test_case.expect_main_frame_loaded,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     content::PageType expected_page_type = test_case.expect_main_frame_loaded
                                                ? content::PAGE_TYPE_NORMAL
@@ -999,7 +999,7 @@
   GURL url = embedded_test_server()->GetURL("google.com",
                                             "/pages_with_script/page2.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType());
 }
 
@@ -1046,7 +1046,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_EQ(test_case.expect_main_frame_loaded,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     content::PageType expected_page_type = test_case.expect_main_frame_loaded
                                                ? content::PAGE_TYPE_NORMAL
@@ -1109,7 +1109,7 @@
     SCOPED_TRACE(base::StringPrintf("Testing %s", url.spec().c_str()));
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    content::RenderFrameHost* main_frame = GetMainFrame();
+    content::RenderFrameHost* main_frame = GetPrimaryMainFrame();
     EXPECT_TRUE(WasFrameWithScriptLoaded(main_frame));
     EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
 
@@ -1157,7 +1157,7 @@
       "example.com",
       "/request_domain_test.html?w.com,x.com,y.com,a.x.com,z.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   ASSERT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
 
   struct {
@@ -1206,7 +1206,7 @@
   GURL url =
       embedded_test_server()->GetURL("example.com", "/domain_type_test.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   ASSERT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
 
   // The loaded page will consist of four pairs of iframes named
@@ -1282,7 +1282,8 @@
 
     // All requests ending with odd numbers should be blocked.
     const bool page_should_load = (i % 2 == 0);
-    EXPECT_EQ(page_should_load, WasFrameWithScriptLoaded(GetMainFrame()));
+    EXPECT_EQ(page_should_load,
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
     content::PageType expected_page_type =
         page_should_load ? content::PAGE_TYPE_NORMAL : content::PAGE_TYPE_ERROR;
     EXPECT_EQ(expected_page_type, GetPageType());
@@ -1357,7 +1358,7 @@
     SCOPED_TRACE(base::StringPrintf("Testing %s", url.spec().c_str()));
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+    EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     GURL final_url = web_contents()->GetLastCommittedURL();
     EXPECT_EQ(test_case.expected_final_url, final_url);
@@ -1382,7 +1383,7 @@
     SCOPED_TRACE(base::StringPrintf("Testing %s", url.spec().c_str()));
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+    EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     GURL final_url = web_contents()->GetLastCommittedURL();
     EXPECT_EQ(test_case.expected_final_url, final_url);
@@ -1525,7 +1526,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_EQ(test_case.expect_main_frame_loaded,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
     content::PageType expected_page_type = test_case.expect_main_frame_loaded
                                                ? content::PAGE_TYPE_NORMAL
                                                : content::PAGE_TYPE_ERROR;
@@ -1577,7 +1578,7 @@
                                             "/pages_with_script/page.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   GURL final_url = web_contents()->GetLastCommittedURL();
   EXPECT_EQ(GURL(redirect_url_for_extension_number(kNumExtensions)), final_url);
 }
@@ -1649,7 +1650,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(url)));
     EXPECT_EQ(test_case.expected_main_frame_loaded,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     if (!test_case.expected_final_url) {
       EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType());
@@ -1719,7 +1720,7 @@
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-    EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+    EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
     GURL final_url = web_contents()->GetLastCommittedURL();
 
     bool expect_redirection = i >= 1 && i <= kNumPatternTypes;
@@ -1842,14 +1843,14 @@
 
     // The url should be blocked in normal context.
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+    EXPECT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
     EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType());
 
     // In incognito context, the url should be blocked if the extension is
     // enabled in incognito mode.
     ASSERT_TRUE(ui_test_utils::NavigateToURL(incognito_browser, url));
     EXPECT_EQ(!expected_enabled_in_incognito,
-              WasFrameWithScriptLoaded(GetMainFrame(incognito_browser)));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame(incognito_browser)));
     content::PageType expected_page_type = expected_enabled_in_incognito
                                                ? content::PAGE_TYPE_ERROR
                                                : content::PAGE_TYPE_NORMAL;
@@ -2182,7 +2183,7 @@
   // With no extension loaded, the request to the script should succeed.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   // NOTE: RulesetMatcher will not see network requests if no rulesets are
   // active.
@@ -2198,7 +2199,7 @@
   // cache.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_FALSE(base::Contains(
       ruleset_manager_observer()->GetAndResetRequestSeen(), observed_url));
 
@@ -2212,7 +2213,7 @@
   // script.js and block it.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_TRUE(base::Contains(
       ruleset_manager_observer()->GetAndResetRequestSeen(), observed_url));
 
@@ -2225,7 +2226,7 @@
   // in the renderer's in-memory cache.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(expect_request_seen,
             base::Contains(ruleset_manager_observer()->GetAndResetRequestSeen(),
                            observed_url));
@@ -2258,7 +2259,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(),
       GURL("http://does.not.resolve.test/pages_with_script/page.html")));
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
 }
 
@@ -2355,7 +2356,7 @@
     )";
     bool collapsed = false;
     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-        GetMainFrame(), base::StringPrintf(kScript, frame_name.c_str()),
+        GetPrimaryMainFrame(), base::StringPrintf(kScript, frame_name.c_str()),
         &collapsed));
     EXPECT_EQ(expect_collapsed, collapsed);
   };
@@ -2368,7 +2369,7 @@
   // Load a page with two iframes (|kFrameName1| and |kFrameName2|). Initially
   // both the frames should be loaded successfully.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   {
     SCOPED_TRACE("No extension loaded");
     test_frame_collapse(kFrameName1, false);
@@ -2382,7 +2383,7 @@
 
   // Reloading the page should cause |kFrameName1| to be collapsed.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   {
     SCOPED_TRACE("Extension loaded initial");
     test_frame_collapse(kFrameName1, true);
@@ -2785,7 +2786,7 @@
     // The page should have loaded correctly.
     EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
     EXPECT_EQ(expect_script_redirected,
-              WasFrameWithScriptLoaded(GetMainFrame()));
+              WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     // The EmbeddedTestServer sees requests after the hostname has been
     // resolved.
@@ -2919,14 +2920,14 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(
                      "example.com", "/pages_with_script/index.html")));
-  EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   // Sanity check that the script.js request is not blocked if does not match a
   // rule.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(
                      "foo.com", "/pages_with_script/index.html")));
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 }
 
 // Tests the dynamic rule support.
@@ -2976,7 +2977,7 @@
   GURL example_url = embedded_test_server()->GetURL("example.com", kUrlPath);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), example_url));
   EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
-  EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(dynamic_redirect_url, web_contents()->GetLastCommittedURL());
 
   // Now add a dynamic rule to allow requests to yahoo.com.
@@ -3183,7 +3184,7 @@
   };
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   // Verify that the badge text is empty when navigation finishes because no
   // actions have been matched.
@@ -3301,7 +3302,7 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  ASSERT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_TRUE(pass_listener.WaitUntilSatisfied());
 }
 
@@ -3351,7 +3352,7 @@
 
   // Ensure the response from the web request listener was ignored and the
   // request was redirected.
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(web_contents()->GetLastCommittedURL(), redirect_url);
 
   // Ensure onBeforeRequest is seen by the web request extension.
@@ -3990,7 +3991,7 @@
   };
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   int first_tab_id = ExtensionTabUtil::GetTabId(web_contents());
   EXPECT_EQ("", extension_1_action->GetDisplayBadgeText(first_tab_id));
@@ -4193,7 +4194,7 @@
                              "extension_1", {URLPattern::kAllUrlsPattern}));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   // Start the onRuleMatchedDebug observer.
   const char kOnRuleMatchedDebugScript[] = R"(
@@ -4278,7 +4279,7 @@
   auto extension_2_id = last_loaded_extension_id();
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   const int first_tab_id = ExtensionTabUtil::GetTabId(web_contents());
 
   // Navigate to abc.com. The rule from |extension_1| should match for
@@ -4297,7 +4298,7 @@
   ASSERT_TRUE(browser()->tab_strip_model()->IsTabSelected(1));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+  ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   const int second_tab_id = ExtensionTabUtil::GetTabId(web_contents());
 
   // Navigate to abc.com from the second tab. The rule from |extension_1| should
@@ -5102,12 +5103,13 @@
   GURL url = embedded_test_server()->GetURL("google.com",
                                             "/pages_with_script/page2.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+  EXPECT_FALSE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
   EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType());
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  ukm::SourceId frame_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId frame_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
       identifiability_metrics_test_helper_.NavigateToBlankAndWaitForMetrics(
@@ -5165,7 +5167,7 @@
     GURL url = embedded_test_server()->GetURL("example.com",
                                               "/page_with_four_frames.html");
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+    ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
     for (const auto& frame_result : expected_results) {
       SCOPED_TRACE(base::StringPrintf("Testing child frame named %s",
@@ -5276,7 +5278,7 @@
       ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
       ASSERT_EQ(content::PAGE_TYPE_NORMAL, GetPageType());
 
-      content::RenderFrameHost* frame = GetMainFrame();
+      content::RenderFrameHost* frame = GetPrimaryMainFrame();
 
       // sub-frame.
       EXPECT_EQ(
@@ -5414,7 +5416,7 @@
       })();
                                           )",
                                             script_src.c_str());
-    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(),
+    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetPrimaryMainFrame(),
                                             script, &success));
     return success;
   }
@@ -5441,7 +5443,7 @@
           })();
         )",
                                             href.c_str(), resources.c_str());
-    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(),
+    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetPrimaryMainFrame(),
                                             script, &success));
     return success;
   }
@@ -6186,7 +6188,7 @@
 
   GURL url = embedded_test_server()->GetURL("abc.com", "/empty.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_frame = GetMainFrame();
+  content::RenderFrameHost* main_frame = GetPrimaryMainFrame();
 
   for (const auto& test_case : test_cases) {
     SCOPED_TRACE(base::StringPrintf("Path: %s", test_case.path.c_str()));
@@ -6276,7 +6278,7 @@
     }
   )";
 
-  content::RenderFrameHost* main_frame = GetMainFrame();
+  content::RenderFrameHost* main_frame = GetPrimaryMainFrame();
 
   std::string actual_blocked;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
@@ -6356,7 +6358,7 @@
     }
   )())";
 
-  content::RenderFrameHost* main_frame = GetMainFrame();
+  content::RenderFrameHost* main_frame = GetPrimaryMainFrame();
   EXPECT_EQ("echo1_default,echo2_include",
             content::EvalJs(main_frame,
                             base::StringPrintf(
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
index da346a2..588e510 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
@@ -92,7 +92,7 @@
     }
     // The |target_render_frame_host| is the main frame of the tab that
     // was requested for capture.
-    target_render_frame_host = web_contents->GetMainFrame();
+    target_render_frame_host = web_contents->GetPrimaryMainFrame();
   } else {
     origin = extension()->url();
     target_name = base::UTF8ToUTF16(GetExtensionTargetName());
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
index 0129aae..15609e7 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -541,7 +541,7 @@
   choose_args.Append("LOAD");
   scoped_refptr<ExtensionFunction> function(
       new api::DeveloperPrivateChoosePathFunction());
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   EXPECT_TRUE(RunFunction(function, choose_args)) << function->GetError();
   std::string path;
   const base::Value::List* result_list = function->GetResultList();
@@ -559,7 +559,7 @@
   choose_args.Append("FILE");
   choose_args.Append("PEM");
   function = new api::DeveloperPrivateChoosePathFunction();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   EXPECT_TRUE(RunFunction(function, choose_args)) << function->GetError();
   result_list = function->GetResultList();
   ASSERT_TRUE(result_list);
@@ -571,7 +571,7 @@
   // Try canceling the file dialog.
   api::EntryPicker::SkipPickerAndAlwaysCancelForTest();
   function = new api::DeveloperPrivateChoosePathFunction();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   EXPECT_FALSE(RunFunction(function, choose_args));
   EXPECT_EQ(std::string("File selection was canceled."), function->GetError());
 }
@@ -588,7 +588,7 @@
   // be added).
   scoped_refptr<ExtensionFunction> function(
       new api::DeveloperPrivateLoadUnpackedFunction());
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ExtensionIdSet current_ids = registry()->enabled_extensions().GetIDs();
   EXPECT_TRUE(RunFunction(function, base::ListValue())) << function->GetError();
   // We should have added one new extension.
@@ -605,7 +605,7 @@
 
   // Try loading a bad extension (it should fail, and we should get an error).
   function = new api::DeveloperPrivateLoadUnpackedFunction();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   base::ListValue unpacked_args;
   base::Value::Dict options;
   options.Set("failQuietly", true);
@@ -638,7 +638,7 @@
 
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -665,7 +665,7 @@
 
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -697,7 +697,7 @@
 
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -730,7 +730,7 @@
     // retry id populated.
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -750,7 +750,7 @@
     // just retries continuously.
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -779,7 +779,7 @@
 
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
@@ -810,7 +810,7 @@
     // Try reloading the extension by supplying the retry id. It should succeed.
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     TestExtensionRegistryObserver observer(registry());
     api_test_utils::RunFunction(function.get(),
                                 base::StringPrintf("[{\"failQuietly\": true,"
@@ -828,7 +828,7 @@
     // Try supplying an invalid retry id. It should fail with an error.
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::string error = api_test_utils::RunFunctionAndReturnError(
         function.get(),
         "[{\"failQuietly\": true,"
@@ -916,7 +916,7 @@
     UnloadedRegistryObserver unload_observer(path, registry());
     auto function =
         base::MakeRefCounted<api::DeveloperPrivateReloadFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     api_test_utils::RunFunction(function.get(), reload_args, profile());
     // Note: no need to validate a saw_load()-type method because the presence
     // in enabled_extensions() indicates the extension was loaded.
@@ -931,7 +931,7 @@
     // Trying to load the extension should result in a load error with the
     // retry GUID populated.
     auto function = base::MakeRefCounted<api::DeveloperPrivateReloadFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(), reload_args, profile());
@@ -950,7 +950,7 @@
     // and the extension should be enabled again.
     auto function =
         base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     TestExtensionRegistryObserver observer(registry());
     std::string args =
         base::StringPrintf(R"([{"failQuietly": true, "populateError": true,
@@ -985,7 +985,7 @@
   {
     auto function = base::MakeRefCounted<
         api::DeveloperPrivateNotifyDragInstallInProgressFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     api_test_utils::RunFunction(function.get(), "[]", profile());
   }
 
@@ -1003,7 +1003,7 @@
     // Try reloading the extension by supplying the retry id. It should succeed.
     auto function =
         base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     TestExtensionRegistryObserver observer(registry());
     api_test_utils::RunFunction(function.get(), kLoadUnpackedArgs, profile());
     scoped_refptr<const Extension> extension =
@@ -1021,7 +1021,7 @@
   {
     auto function = base::MakeRefCounted<
         api::DeveloperPrivateNotifyDragInstallInProgressFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                          profile());
@@ -1032,7 +1032,7 @@
     // the directory) should result in a load error.
     auto function =
         base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     TestExtensionRegistryObserver observer(registry());
     std::unique_ptr<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
@@ -1282,7 +1282,7 @@
   prefs->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   std::string error = extension_function_test_utils::RunFunctionAndReturnError(
       function.get(), "[]", browser());
   EXPECT_THAT(error, testing::HasSubstr("developer mode"));
@@ -1315,7 +1315,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   std::string error = extension_function_test_utils::RunFunctionAndReturnError(
       function.get(), "[]", browser());
   EXPECT_THAT(error, testing::HasSubstr("policy"));
@@ -1358,7 +1358,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
 
   TestExtensionRegistryObserver observer(registry());
   EXPECT_EQ("No dragged path", api_test_utils::RunFunctionAndReturnError(
@@ -1384,7 +1384,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
 
   TestExtensionRegistryObserver observer(registry());
   ASSERT_TRUE(api_test_utils::RunFunction(function.get(), "[]", profile()))
@@ -1408,7 +1408,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
 
   TestExtensionRegistryObserver observer(registry());
   ASSERT_TRUE(api_test_utils::RunFunction(function.get(), "[]", profile()))
@@ -1833,7 +1833,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
 
   TestExtensionRegistryObserver observer(registry());
   ASSERT_TRUE(api_test_utils::RunFunction(function.get(), "[]", profile()))
@@ -2065,7 +2065,7 @@
 
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   std::string error = extension_function_test_utils::RunFunctionAndReturnError(
       function.get(), "[]", browser());
   EXPECT_THAT(error, testing::HasSubstr("Child account"));
diff --git a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc
index 22b9396a..27fa396 100644
--- a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc
+++ b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc
@@ -182,7 +182,7 @@
         url = extension_host->initial_url();
     }
 
-    bool is_iframe = web_contents->GetMainFrame() != host;
+    bool is_iframe = web_contents->GetPrimaryMainFrame() != host;
     content::RenderProcessHost* process = host->GetProcess();
     result->push_back(ConstructView(url, process->GetID(), host->GetRoutingID(),
                                     is_incognito, is_iframe,
@@ -219,7 +219,7 @@
     if (url.is_empty())
       url = window->initial_url();
 
-    content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     result->push_back(ConstructView(
         url, main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(),
         false, false, ConvertViewType(GetViewType(web_contents))));
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index c5997e75..65b3ff5 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -346,13 +346,16 @@
     EXPECT_TRUE(content::WaitForLoadStop(tab));
     EventRouter::Get(current_browser()->profile())
         ->AddEventListener(downloads::OnCreated::kEventName,
-                           tab->GetMainFrame()->GetProcess(), GetExtensionId());
+                           tab->GetPrimaryMainFrame()->GetProcess(),
+                           GetExtensionId());
     EventRouter::Get(current_browser()->profile())
         ->AddEventListener(downloads::OnChanged::kEventName,
-                           tab->GetMainFrame()->GetProcess(), GetExtensionId());
+                           tab->GetPrimaryMainFrame()->GetProcess(),
+                           GetExtensionId());
     EventRouter::Get(current_browser()->profile())
         ->AddEventListener(downloads::OnErased::kEventName,
-                           tab->GetMainFrame()->GetProcess(), GetExtensionId());
+                           tab->GetPrimaryMainFrame()->GetProcess(),
+                           GetExtensionId());
   }
 
   content::RenderProcessHost* AddFilenameDeterminer() {
@@ -364,8 +367,9 @@
         ui::PAGE_TRANSITION_LINK);
     EventRouter::Get(current_browser()->profile())
         ->AddEventListener(downloads::OnDeterminingFilename::kEventName,
-                           tab->GetMainFrame()->GetProcess(), GetExtensionId());
-    return tab->GetMainFrame()->GetProcess();
+                           tab->GetPrimaryMainFrame()->GetProcess(),
+                           GetExtensionId());
+    return tab->GetPrimaryMainFrame()->GetProcess();
   }
 
   void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
@@ -700,9 +704,9 @@
           current_browser(), url, ui::PAGE_TRANSITION_LINK);
       observer->WaitForNavigationFinished();
       function->set_extension(extension_.get());
-      function->SetRenderFrameHost(tab->GetMainFrame());
+      function->SetRenderFrameHost(tab->GetPrimaryMainFrame());
       function->set_source_process_id(
-          tab->GetMainFrame()->GetProcess()->GetID());
+          tab->GetPrimaryMainFrame()->GetProcess()->GetID());
     }
   }
 
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow_browsertest.cc b/chrome/browser/extensions/api/identity/web_auth_flow_browsertest.cc
index 45058d6a..87aaeaf 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow_browsertest.cc
+++ b/chrome/browser/extensions/api/identity/web_auth_flow_browsertest.cc
@@ -117,7 +117,7 @@
 
   // Create a fenced frame into the inner WebContents of the WebAuthFlow.
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       embedded_test_server()->GetURL("/fenced_frames/title1.html")));
 }
 
@@ -145,6 +145,6 @@
 
   // Create a fenced frame into the inner WebContents of the WebAuthFlow.
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(), embedded_test_server()->GetURL("/error"),
-      net::Error::ERR_FAILED));
+      web_contents()->GetPrimaryMainFrame(),
+      embedded_test_server()->GetURL("/error"), net::Error::ERR_FAILED));
 }
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc
index c039a117..c4fd496 100644
--- a/chrome/browser/extensions/api/management/management_api_browsertest.cc
+++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -334,8 +334,10 @@
     const char* const enabled_string = enabled ? "true" : "false";
     if (user_gesture)
       function->set_user_gesture(true);
-    function->SetRenderFrameHost(browser()->tab_strip_model()->
-        GetActiveWebContents()->GetMainFrame());
+    function->SetRenderFrameHost(browser()
+                                     ->tab_strip_model()
+                                     ->GetActiveWebContents()
+                                     ->GetPrimaryMainFrame());
     bool response = test_utils::RunFunction(
         function.get(), base::StringPrintf("[\"%s\", %s]", kId, enabled_string),
         browser(), api_test_utils::NONE);
diff --git a/chrome/browser/extensions/api/management/management_api_unittest.cc b/chrome/browser/extensions/api/management/management_api_unittest.cc
index 754ffad..884e760 100644
--- a/chrome/browser/extensions/api/management/management_api_unittest.cc
+++ b/chrome/browser/extensions/api/management/management_api_unittest.cc
@@ -137,7 +137,7 @@
   scoped_refptr<ManagementSetEnabledFunction> function =
       base::MakeRefCounted<ManagementSetEnabledFunction>();
   if (web_contents)
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   base::Value args(base::Value::Type::LIST);
   args.Append(extension_id);
   args.Append(enabled);
diff --git a/chrome/browser/extensions/api/mdns/mdns_api.cc b/chrome/browser/extensions/api/mdns/mdns_api.cc
index ecd92e2b3..4172338 100644
--- a/chrome/browser/extensions/api/mdns/mdns_api.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_api.cc
@@ -253,7 +253,7 @@
         extensions::ProcessManager::Get(browser_context_)
         ->GetBackgroundHostForExtension(extension_id);
     content::RenderFrameHost* rfh =
-        host ? host->host_contents()->GetMainFrame() : nullptr;
+        host ? host->host_contents()->GetPrimaryMainFrame() : nullptr;
     if (rfh)
       rfh->AddMessageToConsole(level, logged_message);
   }
diff --git a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc
index 0befa520..1eecb57 100644
--- a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc
+++ b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc
@@ -124,7 +124,7 @@
   content::RenderFrameHost* receiver_rfh = nullptr;
   if (include_child_frames) {
     // The target is the active outermost main frame of the WebContents.
-    receiver_rfh = receiver_contents->GetMainFrame();
+    receiver_rfh = receiver_contents->GetPrimaryMainFrame();
   } else if (!receiver_document_id.empty()) {
     ExtensionApiFrameIdMap::DocumentId document_id =
         ExtensionApiFrameIdMap::DocumentIdFromString(receiver_document_id);
diff --git a/chrome/browser/extensions/api/messaging/messaging_apitest.cc b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
index eabd7f5..1edf30f 100644
--- a/chrome/browser/extensions/api/messaging/messaging_apitest.cc
+++ b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
@@ -319,10 +319,11 @@
 
   Result CanConnectAndSendMessagesToMainFrame(const Extension* extension,
                                               const char* message = NULL) {
-    return CanConnectAndSendMessagesToFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        extension,
-        message);
+    return CanConnectAndSendMessagesToFrame(browser()
+                                                ->tab_strip_model()
+                                                ->GetActiveWebContents()
+                                                ->GetPrimaryMainFrame(),
+                                            extension, message);
   }
 
   Result CanConnectAndSendMessagesToIFrame(const Extension* extension,
@@ -347,8 +348,10 @@
   }
 
   testing::AssertionResult AreAnyNonWebApisDefinedForMainFrame() {
-    return AreAnyNonWebApisDefinedForFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+    return AreAnyNonWebApisDefinedForFrame(browser()
+                                               ->tab_strip_model()
+                                               ->GetActiveWebContents()
+                                               ->GetPrimaryMainFrame());
   }
 
   testing::AssertionResult AreAnyNonWebApisDefinedForIFrame() {
@@ -823,8 +826,10 @@
   Browser* incognito_browser = OpenURLOffTheRecord(
       profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true),
       chromium_org_url());
-  content::RenderFrameHost* incognito_frame = incognito_browser->
-      tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* incognito_frame =
+      incognito_browser->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame();
 
   {
     IncognitoConnectability::ScopedAlertTracker alert_tracker(
@@ -861,7 +866,7 @@
   content::RenderFrameHost* incognito_frame =
       incognito_browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
 
   IncognitoConnectability::ScopedAlertTracker alert_tracker(
       IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
@@ -914,7 +919,7 @@
   content::RenderFrameHost* incognito_frame =
       incognito_browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
 
   {
     IncognitoConnectability::ScopedAlertTracker alert_tracker(
@@ -942,8 +947,10 @@
   Browser* incognito_browser = OpenURLOffTheRecord(
       profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true),
       chromium_org_url());
-  content::RenderFrameHost* incognito_frame = incognito_browser->
-      tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* incognito_frame =
+      incognito_browser->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame();
 
   {
     IncognitoConnectability::ScopedAlertTracker alert_tracker(
@@ -983,7 +990,7 @@
   content::RenderFrameHost* incognito_frame1 =
       incognito_browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
   infobars::ContentInfoBarManager* infobar_manager1 =
       infobars::ContentInfoBarManager::FromWebContents(
           incognito_browser->tab_strip_model()->GetActiveWebContents());
@@ -994,7 +1001,7 @@
   content::RenderFrameHost* incognito_frame2 =
       incognito_browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
   infobars::ContentInfoBarManager* infobar_manager2 =
       infobars::ContentInfoBarManager::FromWebContents(
           incognito_browser->tab_strip_model()->GetActiveWebContents());
@@ -1024,7 +1031,7 @@
         ui_test_utils::NavigateToURL(incognito_browser, chromium_org_url()));
     incognito_frame2 = incognito_browser->tab_strip_model()
                            ->GetActiveWebContents()
-                           ->GetMainFrame();
+                           ->GetPrimaryMainFrame();
     EXPECT_NE(incognito_frame1, incognito_frame2);
 
     EXPECT_EQ(1U, infobar_manager1->infobar_count());
@@ -1058,7 +1065,7 @@
   content::RenderFrameHost* incognito_frame =
       incognito_browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
 
   IncognitoConnectability::ScopedAlertTracker alert_tracker(
       IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
@@ -1154,7 +1161,7 @@
   ASSERT_NE(nullptr, popup_contents) << "Could not find WebContents for popup";
 
   // Make sure the popup can connect and send messages to the extension.
-  content::RenderFrameHost* popup_frame = popup_contents->GetMainFrame();
+  content::RenderFrameHost* popup_frame = popup_contents->GetPrimaryMainFrame();
 
   EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(popup_frame, extension.get(),
                                                  nullptr));
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc
index 608227bf..3dcc627 100644
--- a/chrome/browser/extensions/api/processes/processes_api.cc
+++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -477,7 +477,7 @@
 
   // TODO(https://crbug.com/767563): chrome.processes.getProcessIdForTab API
   // incorrectly assumes a *single* renderer process per tab.
-  const int process_id = contents->GetMainFrame()->GetProcess()->GetID();
+  const int process_id = contents->GetPrimaryMainFrame()->GetProcess()->GetID();
   return RespondNow(ArgumentList(
       api::processes::GetProcessIdForTab::Results::Create(process_id)));
 }
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
index b570d193..a892d15 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
@@ -66,7 +66,8 @@
   safe_browsing::ReferrerChain referrer_chain;
   SafeBrowsingNavigationObserverManager::AttributionResult result =
       navigation_observer_manager->IdentifyReferrerChainByRenderFrameHost(
-          contents->GetMainFrame(), kReferrerUserGestureLimit, &referrer_chain);
+          contents->GetPrimaryMainFrame(), kReferrerUserGestureLimit,
+          &referrer_chain);
 
   // If the referrer chain is incomplete we'll append the most recent
   // navigations to referrer chain for diagnostic purposes. This only happens if
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
index 85a7158..a953ce3d 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
@@ -73,7 +73,7 @@
 DesktopMediaID BuildDesktopMediaID(content::WebContents* target_contents,
                                    TabCapture::CaptureOptions* options) {
   content::RenderFrameHost* const target_frame =
-      target_contents->GetMainFrame();
+      target_contents->GetPrimaryMainFrame();
   DesktopMediaID source(
       DesktopMediaID::TYPE_WEB_CONTENTS, DesktopMediaID::kNullId,
       WebContentsMediaCaptureId(target_frame->GetProcess()->GetID(),
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
index b6bcad5..97e03c3 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -155,7 +155,8 @@
                                 ui::PAGE_TRANSITION_LINK, false);
   content::WebContents* web_contents = browser()->OpenURL(params);
 
-  content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* const main_frame =
+      web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(main_frame);
   listener.Reply(base::StringPrintf("web-contents-media-stream://%i:%i",
                                     main_frame->GetProcess()->GetID(),
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
index 6db988e2..65926f8 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -46,8 +46,9 @@
         is_verified_(false),
         is_fullscreened_(false),
         render_process_id_(
-            target_contents->GetMainFrame()->GetProcess()->GetID()),
-        render_frame_id_(target_contents->GetMainFrame()->GetRoutingID()) {
+            target_contents->GetPrimaryMainFrame()->GetProcess()->GetID()),
+        render_frame_id_(
+            target_contents->GetPrimaryMainFrame()->GetRoutingID()) {
     DCHECK(web_contents());
     DCHECK(registry_);
   }
@@ -198,7 +199,8 @@
   requests_.push_back(std::make_unique<LiveRequest>(
       target_contents, extension_id, is_anonymous, this));
 
-  content::RenderFrameHost* const main_frame = caller_contents->GetMainFrame();
+  content::RenderFrameHost* const main_frame =
+      caller_contents->GetPrimaryMainFrame();
   if (main_frame) {
     device_id = content::DesktopStreamsRegistry::GetInstance()->RegisterStream(
         main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(),
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index 6884610..c2204c8 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -464,8 +464,10 @@
       IncognitoModePrefs::Availability::kForced);
   // Run without an explicit "incognito" param.
   scoped_refptr<WindowsCreateFunction> function(new WindowsCreateFunction());
-  function->SetRenderFrameHost(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+  function->SetRenderFrameHost(browser()
+                                   ->tab_strip_model()
+                                   ->GetActiveWebContents()
+                                   ->GetPrimaryMainFrame());
   scoped_refptr<const Extension> extension(ExtensionBuilder("Test").Build());
   function->set_extension(extension.get());
   base::Value::Dict result =
@@ -482,8 +484,10 @@
   Browser* incognito_browser = CreateIncognitoBrowser();
   // Run without an explicit "incognito" param.
   function = new WindowsCreateFunction();
-  function->SetRenderFrameHost(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+  function->SetRenderFrameHost(browser()
+                                   ->tab_strip_model()
+                                   ->GetActiveWebContents()
+                                   ->GetPrimaryMainFrame());
   function->set_extension(extension.get());
   result = utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
       function.get(), kArgsWithoutExplicitIncognitoParam, incognito_browser,
@@ -2088,17 +2092,20 @@
         old_contents, "window.location = '" + web_url2.spec() + "';"));
     nav_observer.Wait();
   }
-  EXPECT_EQ(web_url1, new_contents->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(web_url2, old_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(web_url1,
+            new_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(web_url2,
+            old_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   // Verify that the old and new tab are in the same process.
-  EXPECT_EQ(old_contents->GetMainFrame()->GetProcess(),
-            new_contents->GetMainFrame()->GetProcess());
+  EXPECT_EQ(old_contents->GetPrimaryMainFrame()->GetProcess(),
+            new_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Verify the old and new contents are in the same BrowsingInstance.
-  EXPECT_TRUE(
-      old_contents->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-          new_contents->GetMainFrame()->GetSiteInstance()));
+  EXPECT_TRUE(old_contents->GetPrimaryMainFrame()
+                  ->GetSiteInstance()
+                  ->IsRelatedSiteInstance(
+                      new_contents->GetPrimaryMainFrame()->GetSiteInstance()));
 
   // Verify that the |new_contents| has |window.opener| set.
   std::string location_of_opener;
@@ -2106,7 +2113,7 @@
       new_contents,
       "window.domAutomationController.send(window.opener.location.href)",
       &location_of_opener));
-  EXPECT_EQ(old_contents->GetMainFrame()->GetLastCommittedURL().spec(),
+  EXPECT_EQ(old_contents->GetPrimaryMainFrame()->GetLastCommittedURL().spec(),
             location_of_opener);
 
   // Verify that |new_contents| can find |old_contents| using window.open/name.
@@ -2116,7 +2123,7 @@
       "var w = window.open('', 'old-contents');\n"
       "window.domAutomationController.send(w.location.href);",
       &location_of_other_window));
-  EXPECT_EQ(old_contents->GetMainFrame()->GetLastCommittedURL().spec(),
+  EXPECT_EQ(old_contents->GetPrimaryMainFrame()->GetLastCommittedURL().spec(),
             location_of_other_window);
 }
 
@@ -2148,9 +2155,10 @@
   }
 
   // Verify the old and new contents are NOT in the same BrowsingInstance.
-  EXPECT_FALSE(
-      old_contents->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-          new_contents->GetMainFrame()->GetSiteInstance()));
+  EXPECT_FALSE(old_contents->GetPrimaryMainFrame()
+                   ->GetSiteInstance()
+                   ->IsRelatedSiteInstance(
+                       new_contents->GetPrimaryMainFrame()->GetSiteInstance()));
 
   // Verify that the |new_contents| doesn't have |window.opener| set.
   bool opener_as_bool = true;
@@ -2237,7 +2245,7 @@
         &actual_origin_str));
     EXPECT_EQ(test_case.expected_origin_str, actual_origin_str);
     const bool is_opaque_origin =
-        new_contents->GetMainFrame()->GetLastCommittedOrigin().opaque();
+        new_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque();
     EXPECT_EQ(test_case.expected_origin_str == "null", is_opaque_origin);
   };
   for (size_t i = 0; i < std::size(test_cases); ++i) {
@@ -2266,8 +2274,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), extension_url));
   content::WebContents* extension_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(extension_origin,
-            extension_contents->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(
+      extension_origin,
+      extension_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Create another tab and navigate it to a web page.
   content::WebContents* test_contents = nullptr;
@@ -2279,9 +2288,9 @@
     test_contents = test_contents_observer.GetWebContents();
   }
   EXPECT_EQ(web_origin,
-            test_contents->GetMainFrame()->GetLastCommittedOrigin());
-  EXPECT_NE(extension_contents->GetMainFrame()->GetProcess(),
-            test_contents->GetMainFrame()->GetProcess());
+            test_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+  EXPECT_NE(extension_contents->GetPrimaryMainFrame()->GetProcess(),
+            test_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Use |chrome.tabs.update| API to navigate |test_contents| to an about:blank
   // URL.
@@ -2298,10 +2307,10 @@
   }
 
   // Verify the origin and process of the about:blank tab.
-  content::RenderFrameHost* test_frame = test_contents->GetMainFrame();
+  content::RenderFrameHost* test_frame = test_contents->GetPrimaryMainFrame();
   EXPECT_EQ(about_blank_url, test_frame->GetLastCommittedURL());
-  EXPECT_EQ(extension_contents->GetMainFrame()->GetProcess(),
-            test_contents->GetMainFrame()->GetProcess());
+  EXPECT_EQ(extension_contents->GetPrimaryMainFrame()->GetProcess(),
+            test_contents->GetPrimaryMainFrame()->GetProcess());
   // Note that committing with the extension origin wouldn't be possible when
   // targeting an incognito window (see also IncognitoApiTest.Incognito test).
   EXPECT_EQ(extension_origin, test_frame->GetLastCommittedOrigin());
@@ -2331,8 +2340,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), extension_url));
   content::WebContents* extension_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(extension_origin,
-            extension_contents->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(
+      extension_origin,
+      extension_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Create another tab and navigate it to a web page.
   content::WebContents* test_contents = nullptr;
@@ -2359,12 +2369,12 @@
   }
 
   // Verify the origin and process of the about:newtab tab.
-  content::RenderFrameHost* test_frame = test_contents->GetMainFrame();
+  content::RenderFrameHost* test_frame = test_contents->GetPrimaryMainFrame();
   EXPECT_EQ(chrome_newtab_url, test_frame->GetLastCommittedURL());
   EXPECT_EQ(url::Origin::Create(chrome_newtab_url),
             test_frame->GetLastCommittedOrigin());
-  EXPECT_NE(extension_contents->GetMainFrame()->GetProcess(),
-            test_contents->GetMainFrame()->GetProcess());
+  EXPECT_NE(extension_contents->GetPrimaryMainFrame()->GetProcess(),
+            test_contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 // Tests updating a URL of a web tab to a non-web-accessible-resource of an
@@ -2384,8 +2394,9 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), extension_url));
   content::WebContents* extension_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(extension_origin,
-            extension_contents->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(
+      extension_origin,
+      extension_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Create another tab and navigate it to a web page.
   content::WebContents* test_contents = nullptr;
@@ -2397,9 +2408,9 @@
     test_contents = test_contents_observer.GetWebContents();
   }
   EXPECT_EQ(web_origin,
-            test_contents->GetMainFrame()->GetLastCommittedOrigin());
-  EXPECT_NE(extension_contents->GetMainFrame()->GetProcess(),
-            test_contents->GetMainFrame()->GetProcess());
+            test_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+  EXPECT_NE(extension_contents->GetPrimaryMainFrame()->GetProcess(),
+            test_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Use |chrome.tabs.update| API to navigate |test_contents| to a
   // non-web-accessible-resource of an extension.
@@ -2416,11 +2427,11 @@
   }
 
   // Verify the origin and process of the navigated tab.
-  content::RenderFrameHost* test_frame = test_contents->GetMainFrame();
+  content::RenderFrameHost* test_frame = test_contents->GetPrimaryMainFrame();
   EXPECT_EQ(non_war_url, test_frame->GetLastCommittedURL());
   EXPECT_EQ(extension_origin, test_frame->GetLastCommittedOrigin());
-  EXPECT_EQ(extension_contents->GetMainFrame()->GetProcess(),
-            test_contents->GetMainFrame()->GetProcess());
+  EXPECT_EQ(extension_contents->GetPrimaryMainFrame()->GetProcess(),
+            test_contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 4bc74e1..d1c95bb1 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -568,48 +568,53 @@
   // We only iterate the frames in the active page. We currently do not
   // expose back/forward cached frames or prerender frames in the GetAllFrames
   // API.
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      [](content::WebContents* web_contents,
-         std::vector<GetAllFrames::Results::DetailsType>& result_list,
-         content::RenderFrameHost* render_frame_host) {
-        // Don't expose inner WebContents for the getFrames API.
-        if (content::WebContents::FromRenderFrameHost(render_frame_host) !=
-            web_contents) {
-          return content::RenderFrameHost::FrameIterationAction::kSkipChildren;
-        }
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(
+          [](content::WebContents* web_contents,
+             std::vector<GetAllFrames::Results::DetailsType>& result_list,
+             content::RenderFrameHost* render_frame_host) {
+            // Don't expose inner WebContents for the getFrames API.
+            if (content::WebContents::FromRenderFrameHost(render_frame_host) !=
+                web_contents) {
+              return content::RenderFrameHost::FrameIterationAction::
+                  kSkipChildren;
+            }
 
-        auto* navigation_state =
-            FrameNavigationState::GetForCurrentDocument(render_frame_host);
+            auto* navigation_state =
+                FrameNavigationState::GetForCurrentDocument(render_frame_host);
 
-        if (!navigation_state ||
-            !FrameNavigationState::IsValidUrl(navigation_state->GetUrl())) {
-          return content::RenderFrameHost::FrameIterationAction::kContinue;
-        }
+            if (!navigation_state ||
+                !FrameNavigationState::IsValidUrl(navigation_state->GetUrl())) {
+              return content::RenderFrameHost::FrameIterationAction::kContinue;
+            }
 
-        GetAllFrames::Results::DetailsType frame;
-        frame.url = navigation_state->GetUrl().spec();
-        frame.frame_id = ExtensionApiFrameIdMap::GetFrameId(render_frame_host);
-        frame.parent_frame_id =
-            ExtensionApiFrameIdMap::GetParentFrameId(render_frame_host);
-        frame.document_id =
-            ExtensionApiFrameIdMap::GetDocumentId(render_frame_host).ToString();
-        // Only set the parentDocumentId value if we have a parent.
-        if (content::RenderFrameHost* parent_frame_host =
-                render_frame_host->GetParentOrOuterDocument()) {
-          frame.parent_document_id = std::make_unique<std::string>(
-              ExtensionApiFrameIdMap::GetDocumentId(parent_frame_host)
-                  .ToString());
-        }
-        frame.frame_type =
-            ToString(ExtensionApiFrameIdMap::GetFrameType(render_frame_host));
-        frame.document_lifecycle = ToString(
-            ExtensionApiFrameIdMap::GetDocumentLifecycle(render_frame_host));
-        frame.process_id = render_frame_host->GetProcess()->GetID();
-        frame.error_occurred = navigation_state->GetErrorOccurredInFrame();
-        result_list.push_back(std::move(frame));
-        return content::RenderFrameHost::FrameIterationAction::kContinue;
-      },
-      web_contents, std::ref(result_list)));
+            GetAllFrames::Results::DetailsType frame;
+            frame.url = navigation_state->GetUrl().spec();
+            frame.frame_id =
+                ExtensionApiFrameIdMap::GetFrameId(render_frame_host);
+            frame.parent_frame_id =
+                ExtensionApiFrameIdMap::GetParentFrameId(render_frame_host);
+            frame.document_id =
+                ExtensionApiFrameIdMap::GetDocumentId(render_frame_host)
+                    .ToString();
+            // Only set the parentDocumentId value if we have a parent.
+            if (content::RenderFrameHost* parent_frame_host =
+                    render_frame_host->GetParentOrOuterDocument()) {
+              frame.parent_document_id = std::make_unique<std::string>(
+                  ExtensionApiFrameIdMap::GetDocumentId(parent_frame_host)
+                      .ToString());
+            }
+            frame.frame_type = ToString(
+                ExtensionApiFrameIdMap::GetFrameType(render_frame_host));
+            frame.document_lifecycle =
+                ToString(ExtensionApiFrameIdMap::GetDocumentLifecycle(
+                    render_frame_host));
+            frame.process_id = render_frame_host->GetProcess()->GetID();
+            frame.error_occurred = navigation_state->GetErrorOccurredInFrame();
+            result_list.push_back(std::move(frame));
+            return content::RenderFrameHost::FrameIterationAction::kContinue;
+          },
+          web_contents, std::ref(result_list)));
 
   return RespondNow(ArgumentList(GetAllFrames::Results::Create(result_list)));
 }
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
index 3f4a5130f..8feee12 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -464,11 +464,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kMiddle;
   mouse_event.SetPositionInWidget(7, 7);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
@@ -499,11 +503,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(7, 7);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
@@ -534,11 +542,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(7, 7);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index 9736be94..22053cc4b 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -761,11 +761,15 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(7, 7);
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
@@ -1075,7 +1079,8 @@
   {
     EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile()));
 
-    content::RenderFrameHostWrapper main_frame(web_contents->GetMainFrame());
+    content::RenderFrameHostWrapper main_frame(
+        web_contents->GetPrimaryMainFrame());
     content::RenderFrameHostWrapper child_frame(
         ChildFrameAt(main_frame.get(), 0));
     ASSERT_TRUE(child_frame);
@@ -1098,7 +1103,8 @@
   // The runner will have refreshed the page, and the extension will have
   // received access to the main-frame ("a.com"). It should still not be able to
   // intercept the cross-origin sub-frame requests to "b.com" and "c.com".
-  content::RenderFrameHostWrapper main_frame(web_contents->GetMainFrame());
+  content::RenderFrameHostWrapper main_frame(
+      web_contents->GetPrimaryMainFrame());
   content::RenderFrameHostWrapper child_frame(
       ChildFrameAt(main_frame.get(), 0));
   const std::string kChildHost = child_frame->GetLastCommittedURL().host();
@@ -1313,7 +1319,7 @@
       xhr.onerror = () => {window.domAutomationController.send(false);};
       xhr.send();)";
   bool success = false;
-  EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(),
+  EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetPrimaryMainFrame(),
                                           kRequest, &success));
   // Requests always fail due to cross origin nature.
   EXPECT_FALSE(success);
@@ -1810,8 +1816,8 @@
         browser(),
         embedded_test_server()->GetURL(testcase.navigate_before_start,
                                        "/extensions/body1.html")));
-    PerformXhrInFrame(web_contents->GetMainFrame(), testcase.xhr_domain, port,
-                      "extensions/api_test/webrequest/xhr/data.json");
+    PerformXhrInFrame(web_contents->GetPrimaryMainFrame(), testcase.xhr_domain,
+                      port, "extensions/api_test/webrequest/xhr/data.json");
 
     // Ensure that the extension wasn't able to intercept the request if it
     // didn't have permission to the initiator or the request url.
@@ -1893,7 +1899,7 @@
   auto pending_receiver = factory.BindNewPipeAndPassReceiver();
   auto temp_web_contents =
       WebContents::Create(WebContents::CreateParams(temp_profile));
-  content::RenderFrameHost* frame = temp_web_contents->GetMainFrame();
+  content::RenderFrameHost* frame = temp_web_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(api->MaybeProxyURLLoaderFactory(
       frame->GetProcess()->GetBrowserContext(), frame,
       frame->GetProcess()->GetID(),
@@ -2339,7 +2345,7 @@
   // The extension shouldn't have currently received any webRequest events,
   // since it doesn't have permission (and shouldn't receive any from an XHR).
   EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile()));
-  PerformXhrInFrame(web_contents->GetMainFrame(), protected_domain, port,
+  PerformXhrInFrame(web_contents->GetPrimaryMainFrame(), protected_domain, port,
                     kXhrPath);
   EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile()));
 
@@ -2358,7 +2364,7 @@
   // didn't block the events.
   EXPECT_EQ(0, xhr_count);
   // And the extension should also block future events.
-  PerformXhrInFrame(web_contents->GetMainFrame(), protected_domain, port,
+  PerformXhrInFrame(web_contents->GetPrimaryMainFrame(), protected_domain, port,
                     kXhrPath);
   EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile()));
 }
@@ -2540,7 +2546,7 @@
   // Make a XHR request which redirects. The final response should not include
   // the Location header.
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-  PerformXhrInFrame(web_contents->GetMainFrame(),
+  PerformXhrInFrame(web_contents->GetPrimaryMainFrame(),
                     embedded_test_server()->host_port_pair().host(),
                     embedded_test_server()->port(), "redirect-and-wait");
   EXPECT_EQ(
@@ -3283,10 +3289,12 @@
       base::Time::Now() + base::Days(100), true, run_loop.QuitClosure());
   run_loop.Run();
 
-  PerformXhrInFrame(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      https_test_server.host_port_pair().host(), https_test_server.port(),
-      "echo");
+  PerformXhrInFrame(browser()
+                        ->tab_strip_model()
+                        ->GetActiveWebContents()
+                        ->GetPrimaryMainFrame(),
+                    https_test_server.host_port_pair().host(),
+                    https_test_server.port(), "echo");
   EXPECT_GT(
       GetCountFromBackgroundPage(extension, profile(), "window.headerCount"),
       0);
@@ -3404,7 +3412,7 @@
           })();
         )",
                                             script_src.c_str());
-    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(),
+    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetPrimaryMainFrame(),
                                             script, &success));
     return success;
   }
@@ -3431,7 +3439,7 @@
           })();
         )",
                                             href.c_str(), resources.c_str());
-    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(),
+    EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetPrimaryMainFrame(),
                                             script, &success));
     return success;
   }
@@ -4278,7 +4286,7 @@
   EXPECT_EQ(page_with_iframe_url, web_contents->GetLastCommittedURL());
 
   content::RenderFrameHostWrapper child_frame(
-      ChildFrameAt(web_contents->GetMainFrame(), 0));
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0));
   ASSERT_TRUE(child_frame);
 
   GURL redirected_url =
@@ -4329,7 +4337,8 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  ukm::SourceId frame_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId frame_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
       identifiability_metrics_test_helper_.NavigateToBlankAndWaitForMetrics(
@@ -4357,7 +4366,8 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  ukm::SourceId frame_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId frame_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
       identifiability_metrics_test_helper_.NavigateToBlankAndWaitForMetrics(
@@ -4386,7 +4396,8 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  ukm::SourceId frame_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId frame_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
       identifiability_metrics_test_helper_.NavigateToBlankAndWaitForMetrics(
@@ -4588,7 +4599,7 @@
       xhr.send();)";
   bool success = false;
   ASSERT_TRUE(ExecuteScriptAndExtractBool(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       base::StringPrintf(kCORSPreflightedRequest, kCORSUrl,
                          kCustomPreflightHeader),
       &success));
diff --git a/chrome/browser/extensions/api/web_view/chrome_web_view_internal_api.cc b/chrome/browser/extensions/api/web_view/chrome_web_view_internal_api.cc
index cb6cc4e6..eb49b55 100644
--- a/chrome/browser/extensions/api/web_view/chrome_web_view_internal_api.cc
+++ b/chrome/browser/extensions/api/web_view/chrome_web_view_internal_api.cc
@@ -30,7 +30,7 @@
       Profile::FromBrowserContext(browser_context())->IsOffTheRecord(),
       MenuItem::ExtensionKey(
           extension_id(),
-          GetSenderWebContents()->GetMainFrame()->GetProcess()->GetID(),
+          GetSenderWebContents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
           params->instance_id));
 
   if (params->create_properties.id.get()) {
@@ -64,7 +64,7 @@
       profile->IsOffTheRecord(),
       MenuItem::ExtensionKey(
           extension_id(),
-          GetSenderWebContents()->GetMainFrame()->GetProcess()->GetID(),
+          GetSenderWebContents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
           params->instance_id));
 
   if (params->id.as_string)
@@ -94,7 +94,7 @@
       Profile::FromBrowserContext(browser_context())->IsOffTheRecord(),
       MenuItem::ExtensionKey(
           extension_id(),
-          GetSenderWebContents()->GetMainFrame()->GetProcess()->GetID(),
+          GetSenderWebContents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
           params->instance_id));
 
   if (params->menu_item_id.as_string) {
@@ -128,7 +128,7 @@
       MenuManager::Get(Profile::FromBrowserContext(browser_context()));
   menu_manager->RemoveAllContextItems(MenuItem::ExtensionKey(
       extension_id(),
-      GetSenderWebContents()->GetMainFrame()->GetProcess()->GetID(),
+      GetSenderWebContents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
       params->instance_id));
 
   return RespondNow(NoArguments());
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
index c2f89b0..d1750e2 100644
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
@@ -110,7 +110,7 @@
                         content::RenderProcessHost** target_host,
                         content::WebContents* guest_contents) {
       *guests_found = *guests_found + 1;
-      *target_host = guest_contents->GetMainFrame()->GetProcess();
+      *target_host = guest_contents->GetPrimaryMainFrame()->GetProcess();
       // Don't short-circuit, so we can count how many other guest contents
       // there are.
       return false;
@@ -179,7 +179,8 @@
     return nullptr;
   }
 
-  content::RenderProcessHost* rph = contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* rph =
+      contents->GetPrimaryMainFrame()->GetProcess();
   if (!rph) {
     *error = "Failed to get RPH.";
   }
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc
index c52faf9..b6e3134 100644
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc
@@ -401,7 +401,7 @@
     auto* manager = WebRtcEventLogManager::GetInstance();
 
     content::RenderFrameHost* render_frame_host =
-        web_contents()->GetMainFrame();
+        web_contents()->GetPrimaryMainFrame();
     const content::GlobalRenderFrameHostId frame_id =
         render_frame_host->GetGlobalId();
     const base::ProcessId pid =
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
index 032a8cb..4d99658 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
@@ -232,7 +232,7 @@
   ASSERT_TRUE(content::ExecuteScript(web_contents, "dropFrame()"));
   EXPECT_TRUE(WaitForLoadStop(web_contents));
   content::RenderFrameHost* subframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(subframe);
 
   // The subframe load should fail due to XFO.
@@ -255,7 +255,7 @@
   ASSERT_TRUE(content::ExecuteScript(web_contents, "dropFrame()"));
   EXPECT_TRUE(WaitForLoadStop(web_contents));
   content::RenderFrameHost* subframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(subframe);
 
   // The subframe load should fail due to XFO.
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
index 4a6b62dc..ef7483b 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
@@ -430,7 +430,7 @@
   // Confirm request dialog
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     ScopedTestDialogAutoConfirm auto_confirm(
         ScopedTestDialogAutoConfirm::ACCEPT);
@@ -445,7 +445,7 @@
   // Show pending request dialog which can only be canceled.
   function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     ScopedTestDialogAutoConfirm auto_cancel(
         ScopedTestDialogAutoConfirm::CANCEL);
@@ -467,7 +467,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_cancel(ScopedTestDialogAutoConfirm::CANCEL);
 
   api_test_utils::RunFunction(function.get(),
@@ -487,7 +487,7 @@
 
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     ScopedTestDialogAutoConfirm auto_confirm(
         ScopedTestDialogAutoConfirm::ACCEPT);
@@ -513,7 +513,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     ScopedTestDialogAutoConfirm auto_cancel(
         ScopedTestDialogAutoConfirm::CANCEL);
@@ -536,7 +536,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     ScopedTestDialogAutoConfirm auto_confirm(
         ScopedTestDialogAutoConfirm::ACCEPT);
@@ -551,7 +551,7 @@
   EnableExtensionRequest(false);
   function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   {
     // Successfully confirm the install prompt and the API returns an empty
     // string without error.
@@ -576,7 +576,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
 
   api_test_utils::RunFunction(function.get(),
@@ -596,7 +596,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
 
   api_test_utils::RunFunction(function.get(),
@@ -614,7 +614,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
 
   api_test_utils::RunFunction(function.get(),
@@ -631,7 +631,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
 
   api_test_utils::RunFunction(function.get(),
@@ -648,7 +648,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
 
   std::unique_ptr<base::Value> response = RunFunctionAndReturnValue(
@@ -673,7 +673,7 @@
                                                           nullptr);
     auto function = base::MakeRefCounted<
         WebstorePrivateBeginInstallWithManifest3Function>();
-    function->SetRenderFrameHost(web_contents->GetMainFrame());
+    function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     ScopedTestDialogAutoConfirm auto_confirm(
         ScopedTestDialogAutoConfirm::ACCEPT);
 
@@ -772,7 +772,7 @@
       content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
   auto function =
       base::MakeRefCounted<WebstorePrivateBeginInstallWithManifest3Function>();
-  function->SetRenderFrameHost(web_contents->GetMainFrame());
+  function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
   ScopedTestDialogAutoConfirm auto_confirm(test_case.dialog_action);
 
   std::string args =
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index abef001..878234c 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -100,7 +100,7 @@
     EXPECT_TRUE(process_map->Contains(browser()
                                           ->tab_strip_model()
                                           ->GetWebContentsAt(1)
-                                          ->GetMainFrame()
+                                          ->GetPrimaryMainFrame()
                                           ->GetProcess()
                                           ->GetID()));
     EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
@@ -115,7 +115,7 @@
     EXPECT_TRUE(process_map->Contains(browser()
                                           ->tab_strip_model()
                                           ->GetWebContentsAt(2)
-                                          ->GetMainFrame()
+                                          ->GetPrimaryMainFrame()
                                           ->GetProcess()
                                           ->GetID()));
     EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
@@ -127,8 +127,8 @@
     ASSERT_EQ(3, browser()->tab_strip_model()->count());
     WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
     WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
-    EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
-              tab2->GetMainFrame()->GetProcess());
+    EXPECT_NE(tab1->GetPrimaryMainFrame()->GetProcess(),
+              tab2->GetPrimaryMainFrame()->GetProcess());
 
     // Opening tabs with window.open should keep the page in the opener's
     // process.
@@ -172,7 +172,7 @@
   EXPECT_TRUE(process_map->Contains(browser()
                                         ->tab_strip_model()
                                         ->GetWebContentsAt(1)
-                                        ->GetMainFrame()
+                                        ->GetPrimaryMainFrame()
                                         ->GetProcess()
                                         ->GetID()));
   EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
@@ -184,7 +184,7 @@
   EXPECT_TRUE(process_map->Contains(browser()
                                         ->tab_strip_model()
                                         ->GetWebContentsAt(2)
-                                        ->GetMainFrame()
+                                        ->GetPrimaryMainFrame()
                                         ->GetProcess()
                                         ->GetID()));
   EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
@@ -197,7 +197,7 @@
   EXPECT_FALSE(process_map->Contains(browser()
                                          ->tab_strip_model()
                                          ->GetWebContentsAt(3)
-                                         ->GetMainFrame()
+                                         ->GetPrimaryMainFrame()
                                          ->GetProcess()
                                          ->GetID()));
   EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
@@ -209,16 +209,18 @@
   ASSERT_EQ(4, browser()->tab_strip_model()->count());
   WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
 
-  EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
-                                                   ->tab_strip_model()
-                                                   ->GetWebContentsAt(2)
-                                                   ->GetMainFrame()
-                                                   ->GetProcess());
-  EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
-                                                   ->tab_strip_model()
-                                                   ->GetWebContentsAt(3)
-                                                   ->GetMainFrame()
-                                                   ->GetProcess());
+  EXPECT_EQ(tab->GetPrimaryMainFrame()->GetProcess(),
+            browser()
+                ->tab_strip_model()
+                ->GetWebContentsAt(2)
+                ->GetPrimaryMainFrame()
+                ->GetProcess());
+  EXPECT_NE(tab->GetPrimaryMainFrame()->GetProcess(),
+            browser()
+                ->tab_strip_model()
+                ->GetWebContentsAt(3)
+                ->GetPrimaryMainFrame()
+                ->GetProcess());
 
   // Now let's do the same using window.open. The same should happen.
   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
@@ -239,26 +241,29 @@
       browser()->tab_strip_model()->GetWebContentsAt(2), non_app_url));
   EXPECT_TRUE(NavigateInRenderer(
       browser()->tab_strip_model()->GetWebContentsAt(3), app_url));
-  EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
-                                                   ->tab_strip_model()
-                                                   ->GetWebContentsAt(2)
-                                                   ->GetMainFrame()
-                                                   ->GetProcess());
-  EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
-                                                   ->tab_strip_model()
-                                                   ->GetWebContentsAt(3)
-                                                   ->GetMainFrame()
-                                                   ->GetProcess());
+  EXPECT_NE(tab->GetPrimaryMainFrame()->GetProcess(),
+            browser()
+                ->tab_strip_model()
+                ->GetWebContentsAt(2)
+                ->GetPrimaryMainFrame()
+                ->GetProcess());
+  EXPECT_EQ(tab->GetPrimaryMainFrame()->GetProcess(),
+            browser()
+                ->tab_strip_model()
+                ->GetWebContentsAt(3)
+                ->GetPrimaryMainFrame()
+                ->GetProcess());
 
   // If one of the popup tabs navigates back to the app, window.opener should
   // be valid.
   EXPECT_TRUE(NavigateInRenderer(
       browser()->tab_strip_model()->GetWebContentsAt(6), app_url));
-  EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
-                                                   ->tab_strip_model()
-                                                   ->GetWebContentsAt(6)
-                                                   ->GetMainFrame()
-                                                   ->GetProcess());
+  EXPECT_EQ(tab->GetPrimaryMainFrame()->GetProcess(),
+            browser()
+                ->tab_strip_model()
+                ->GetWebContentsAt(6)
+                ->GetPrimaryMainFrame()
+                ->GetProcess());
   bool windowOpenerValid = false;
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
       browser()->tab_strip_model()->GetWebContentsAt(6),
@@ -319,12 +324,12 @@
   EXPECT_EQ(browser()
                 ->tab_strip_model()
                 ->GetWebContentsAt(1)
-                ->GetMainFrame()
+                ->GetPrimaryMainFrame()
                 ->GetProcess(),
             browser()
                 ->tab_strip_model()
                 ->GetWebContentsAt(2)
-                ->GetMainFrame()
+                ->GetPrimaryMainFrame()
                 ->GetProcess());
 }
 
@@ -347,8 +352,8 @@
       browser(), base_url.Resolve("path1/empty.html")));
   LOG(INFO) << "Loading path1/empty.html - done.";
   WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Load app and re-navigate to the page.
   LOG(INFO) << "Loading extension.";
@@ -360,8 +365,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), base_url.Resolve("path1/empty.html")));
   LOG(INFO) << "Loading path1/empty.html - done.";
-  EXPECT_TRUE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_TRUE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Disable app and re-navigate to the page.
   LOG(INFO) << "Disabling extension.";
@@ -371,8 +376,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), base_url.Resolve("path1/empty.html")));
   LOG(INFO) << "Loading path1/empty.html - done.";
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 }
 
 // Ensure that reloading a URL after installing or uninstalling it as an app
@@ -403,8 +408,8 @@
   LOG(INFO) << "Navigate to path1/empty.html - done.";
   WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
   content::NavigationController& controller = contents->GetController();
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
   // The test starts with about:blank, then navigates to path1/empty.html,
   // so there should be two entries.
   EXPECT_EQ(2, controller.GetEntryCount());
@@ -419,8 +424,8 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   reload_observer.Wait();
   LOG(INFO) << "Reloading - done.";
-  EXPECT_TRUE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_TRUE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
   // Reloading, even with changing SiteInstance/process should not add any
   // more entries.
   EXPECT_EQ(2, controller.GetEntryCount());
@@ -435,8 +440,8 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   reload_observer2.Wait();
   LOG(INFO) << "Reloading - done.";
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
   EXPECT_EQ(2, controller.GetEntryCount());
 }
 
@@ -467,8 +472,8 @@
       browser(), base_url.Resolve("path1/empty.html")));
   LOG(INFO) << "Navigate to path1/empty.html - done.";
   WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Enable app and reload via JavaScript.
   LOG(INFO) << "Enabling extension.";
@@ -480,8 +485,8 @@
   ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
   js_reload_observer.Wait();
   LOG(INFO) << "Executing location.reload() - done.";
-  EXPECT_TRUE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_TRUE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Disable app and reload via JavaScript.
   LOG(INFO) << "Disabling extension.";
@@ -493,8 +498,8 @@
   ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
   js_reload_observer2.Wait();
   LOG(INFO) << "Executing location = location - done.";
-  EXPECT_FALSE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_FALSE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 }
 
 // Similar to the previous test, but ensure that popup blocking bypass
@@ -606,7 +611,7 @@
   content::RenderProcessHost* process = browser()
                                             ->tab_strip_model()
                                             ->GetWebContentsAt(0)
-                                            ->GetMainFrame()
+                                            ->GetPrimaryMainFrame()
                                             ->GetProcess();
   EXPECT_TRUE(process_map->Contains(process->GetID()));
 
@@ -618,7 +623,7 @@
   EXPECT_TRUE(content::WaitForLoadStop(popup_contents));
 
   content::RenderProcessHost* popup_process =
-      popup_contents->GetMainFrame()->GetProcess();
+      popup_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_EQ(process, popup_process);
   EXPECT_TRUE(process_map->Contains(popup_process->GetID()));
 }
@@ -635,8 +640,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), base_url.Resolve("path1/empty.html")));
   WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
-  EXPECT_TRUE(
-      process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
+  EXPECT_TRUE(process_map->Contains(
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
   bool is_installed = false;
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
       contents,
diff --git a/chrome/browser/extensions/chrome_app_api_browsertest.cc b/chrome/browser/extensions/chrome_app_api_browsertest.cc
index 91fcc95..4e16bbc 100644
--- a/chrome/browser/extensions/chrome_app_api_browsertest.cc
+++ b/chrome/browser/extensions/chrome_app_api_browsertest.cc
@@ -39,8 +39,10 @@
   }
 
   bool IsAppInstalledInMainFrame() {
-    return IsAppInstalledInFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+    return IsAppInstalledInFrame(browser()
+                                     ->tab_strip_model()
+                                     ->GetActiveWebContents()
+                                     ->GetPrimaryMainFrame());
   }
   bool IsAppInstalledInIFrame() {
     return IsAppInstalledInFrame(GetIFrame());
@@ -56,8 +58,10 @@
   }
 
   std::string InstallStateInMainFrame() {
-    return InstallStateInFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+    return InstallStateInFrame(browser()
+                                   ->tab_strip_model()
+                                   ->GetActiveWebContents()
+                                   ->GetPrimaryMainFrame());
   }
   std::string InstallStateInIFrame() {
     return InstallStateInFrame(GetIFrame());
@@ -74,8 +78,10 @@
   }
 
   std::string RunningStateInMainFrame() {
-    return RunningStateInFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+    return RunningStateInFrame(browser()
+                                   ->tab_strip_model()
+                                   ->GetActiveWebContents()
+                                   ->GetPrimaryMainFrame());
   }
   std::string RunningStateInIFrame() {
     return RunningStateInFrame(GetIFrame());
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
index 5716f76..a519230 100644
--- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
+++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -678,7 +678,7 @@
   // webview tags as well as hosts that happen to match the id of an
   // installed extension would get the wrong preferences.
   const GURL& site_url =
-      web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL();
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL();
   if (!site_url.SchemeIs(kExtensionScheme))
     return false;
 
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index 24cae30..645f706 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -861,7 +861,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   EXPECT_EQ(new_tab_override->GetResourceURL("newtab.html"),
-            tab_contents->GetMainFrame()->GetLastCommittedURL());
+            tab_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_FALSE(listener.was_satisfied());
   listener.Reset();
 
@@ -1500,9 +1500,9 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_Iframe_Allowed) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", about_blank());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", about_blank());
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(about_blank(), render_frame_host->GetLastCommittedURL());
   EXPECT_TRUE(DidScriptRunInFrame(render_frame_host));
@@ -1513,9 +1513,9 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_Iframe_Disallowed) {
   content::WebContents* tab = NavigateTab(disallowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", about_blank());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", about_blank());
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(about_blank(), render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1527,7 +1527,7 @@
                        MatchAboutBlank_Popup_Allowed) {
   content::WebContents* tab = NavigateTab(allowed_url());
   content::WebContents* popup = OpenPopup(tab, about_blank());
-  EXPECT_TRUE(DidScriptRunInFrame(popup->GetMainFrame()));
+  EXPECT_TRUE(DidScriptRunInFrame(popup->GetPrimaryMainFrame()));
 }
 
 // Injection should fail on a popup to about:blank created by a disallowed site.
@@ -1535,7 +1535,7 @@
                        MatchAboutBlank_Popup_Disallowed) {
   content::WebContents* tab = NavigateTab(disallowed_url());
   content::WebContents* popup = OpenPopup(tab, about_blank());
-  EXPECT_FALSE(DidScriptRunInFrame(popup->GetMainFrame()));
+  EXPECT_FALSE(DidScriptRunInFrame(popup->GetPrimaryMainFrame()));
 }
 
 // Browser-initiated navigations do not have a separate precursor tuple, so
@@ -1543,7 +1543,7 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_BrowserOpened) {
   content::WebContents* tab = NavigateTab(about_blank());
-  EXPECT_FALSE(DidScriptRunInFrame(tab->GetMainFrame()));
+  EXPECT_FALSE(DidScriptRunInFrame(tab->GetPrimaryMainFrame()));
 }
 
 // Tests injecting a content script when the iframe rewrites the parent to be
@@ -1576,7 +1576,7 @@
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(null_document_url(), tab->GetLastCommittedURL());
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   // Sanity check: The main frame should have been re-written. The test passes
   // if there's no crash. Since the iframe rewrites the parent synchronously
   // after sending the "navigated" message, there's no risk of a race here.
@@ -1591,10 +1591,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_BlobFrame) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  GURL blob_url = CreateBlobURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", blob_url);
+  GURL blob_url = CreateBlobURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", blob_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(blob_url, render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1605,9 +1605,9 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_DataFrame) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", data_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", data_url());
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(data_url(), render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1617,10 +1617,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest,
                        MatchAboutBlank_FilesystemFrame) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  GURL filesystem_url = CreateFilesystemURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", filesystem_url);
+  GURL filesystem_url = CreateFilesystemURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", filesystem_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(filesystem_url, render_frame_host->GetLastCommittedURL());
 
@@ -1640,19 +1640,20 @@
   content::WebContents* tab =
       NavigateTab(non_matching_path_specific_iframe_url());
   // Navigate the child frame to the URL that matches the path requirement.
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", path_specific_allowed_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]",
+                 path_specific_allowed_url());
 
   content::RenderFrameHost* child_frame =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
 
   EXPECT_EQ(path_specific_allowed_url(), child_frame->GetLastCommittedURL());
   // The script should have ran in the child frame (which matches the pattern),
   // but not the parent frame (which doesn't match the path component).
   EXPECT_TRUE(DidScriptRunInFrame(child_frame));
-  EXPECT_FALSE(DidScriptRunInFrame(tab->GetMainFrame()));
+  EXPECT_FALSE(DidScriptRunInFrame(tab->GetPrimaryMainFrame()));
 
   // Now, navigate the iframe to an about:blank URL.
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", about_blank());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", about_blank());
 
   // Unlike match_origin_as_fallback, match_about_blank will attempt to climb
   // the frame tree to find an ancestor with path. This results in finding the
@@ -1686,9 +1687,9 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        DataURLInjection_SimpleIframe_Allowed) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", data_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", data_url());
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(data_url(), render_frame_host->GetLastCommittedURL());
   EXPECT_TRUE(DidScriptRunInFrame(render_frame_host));
@@ -1699,9 +1700,9 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        DataURLInjection_SimpleIframe_Disallowed) {
   content::WebContents* tab = NavigateTab(disallowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", data_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", data_url());
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(data_url(), render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1711,10 +1712,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        BlobURLInjection_SimpleIframe_Allowed) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  GURL blob_url = CreateBlobURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", blob_url);
+  GURL blob_url = CreateBlobURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", blob_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(blob_url, render_frame_host->GetLastCommittedURL());
   EXPECT_TRUE(DidScriptRunInFrame(render_frame_host));
@@ -1725,10 +1726,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        BlobURLInjection_SimpleIframe_Disallowed) {
   content::WebContents* tab = NavigateTab(disallowed_url_with_iframe());
-  GURL blob_url = CreateBlobURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", blob_url);
+  GURL blob_url = CreateBlobURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", blob_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(blob_url, render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1738,10 +1739,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        FilesystemURLInjection_SimpleIframe_Allowed) {
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  GURL filesystem_url = CreateFilesystemURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", filesystem_url);
+  GURL filesystem_url = CreateFilesystemURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", filesystem_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(filesystem_url, render_frame_host->GetLastCommittedURL());
   EXPECT_TRUE(DidScriptRunInFrame(render_frame_host));
@@ -1752,10 +1753,10 @@
 IN_PROC_BROWSER_TEST_F(ContentScriptMatchOriginAsFallbackTest,
                        FilesystemURLInjection_SimpleIframe_Disallowed) {
   content::WebContents* tab = NavigateTab(disallowed_url_with_iframe());
-  GURL filesystem_url = CreateFilesystemURL(tab->GetMainFrame());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", filesystem_url);
+  GURL filesystem_url = CreateFilesystemURL(tab->GetPrimaryMainFrame());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", filesystem_url);
   content::RenderFrameHost* render_frame_host =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(render_frame_host);
   EXPECT_EQ(filesystem_url, render_frame_host->GetLastCommittedURL());
   EXPECT_FALSE(DidScriptRunInFrame(render_frame_host));
@@ -1773,12 +1774,12 @@
       nested_frame_src.c_str());
 
   const GURL data_url(base::StrCat({"data:text/html,", nested_data_html}));
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", data_url);
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", data_url);
 
   // The extension should have injected in both iframes, since they each
   // "belong" to the original, allowed site.
   content::RenderFrameHost* first_data =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(first_data);
   EXPECT_EQ(data_url, first_data->GetLastCommittedURL());
   EXPECT_TRUE(DidScriptRunInFrame(first_data));
@@ -1797,9 +1798,10 @@
   // Open a page to a protected site, and then navigate an iframe to an allowed
   // site with an iframe.
   content::WebContents* tab = NavigateTab(disallowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]", allowed_url_with_iframe());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]",
+                 allowed_url_with_iframe());
   content::RenderFrameHost* example_com_frame =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(allowed_url_with_iframe(),
             example_com_frame->GetLastCommittedURL());
 
@@ -1819,7 +1821,7 @@
 
   // Now, navigate the iframe within the allowed site to a data URL, but do so
   // from the top frame (which the extension is not allowed to access).
-  NavigateIframe(tab->GetMainFrame(), "frames[0].frames[0]", data_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0].frames[0]", data_url());
 
   {
     // Since the top frame (which the extension may not access) is now the
@@ -1840,10 +1842,10 @@
   // Open a page to an allowed site, and then navigate an iframe to a disallowed
   // site with an iframe.
   content::WebContents* tab = NavigateTab(allowed_url_with_iframe());
-  NavigateIframe(tab->GetMainFrame(), "frames[0]",
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]",
                  disallowed_url_with_iframe());
   content::RenderFrameHost* example_com_frame =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(disallowed_url_with_iframe(),
             example_com_frame->GetLastCommittedURL());
 
@@ -1864,7 +1866,7 @@
 
   // Now, navigate the iframe within the disallowed site to a data URL, but do
   // so from the top frame (which the extension is allowed to access).
-  NavigateIframe(tab->GetMainFrame(), "frames[0].frames[0]", data_url());
+  NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0].frames[0]", data_url());
 
   {
     content::RenderFrameHost* data_url_host = content::FrameMatchingPredicate(
diff --git a/chrome/browser/extensions/content_script_tracker_browsertest.cc b/chrome/browser/extensions/content_script_tracker_browsertest.cc
index bc51f13..8b7ab82 100644
--- a/chrome/browser/extensions/content_script_tracker_browsertest.cc
+++ b/chrome/browser/extensions/content_script_tracker_browsertest.cc
@@ -179,7 +179,7 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(web_contents, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *web_contents->GetMainFrame()->GetProcess(), extension->id()));
+      *web_contents->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *background_frame->GetProcess(), extension->id()));
 
@@ -195,7 +195,7 @@
   EXPECT_EQ("content script has run",
             content::EvalJs(web_contents, "document.body.innerText"));
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *web_contents->GetMainFrame()->GetProcess(), extension->id()));
+      *web_contents->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *background_frame->GetProcess(), extension->id()));
 
@@ -211,7 +211,7 @@
   EXPECT_EQ("This page has a title.",
             content::EvalJs(web_contents, "document.body.innerText"));
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *web_contents->GetMainFrame()->GetProcess(), extension->id()));
+      *web_contents->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *background_frame->GetProcess(), extension->id()));
 }
@@ -267,7 +267,7 @@
   EXPECT_EQ("content script has run",
             content::EvalJs(web_contents, "document.body.innerText"));
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *web_contents->GetMainFrame()->GetProcess(), extension->id()));
+      *web_contents->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 }
 
 // Tests tracking of content scripts injected/declared via `content_scripts`
@@ -309,7 +309,7 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 
   // Navigate to a test page that *is* covered by `content_scripts.matches`
   // manifest entry above.
@@ -331,7 +331,7 @@
 
     // Verify that ContentScriptTracker detected the injection.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *second_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *second_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 
   // Verify that the initial tab still is still correctly absent from
@@ -339,7 +339,7 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 }
 
 // Ensure ContentScriptTracker correctly tracks script injections in frames
@@ -412,7 +412,7 @@
   // been run in the `popup`.  This verifies product code - this is the main
   // verification in this test.
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *popup->GetMainFrame()->GetProcess(), extension_id));
+      *popup->GetPrimaryMainFrame()->GetProcess(), extension_id));
 }
 
 class ContentScriptTrackerMatchOriginAsFallbackBrowserTest
@@ -470,7 +470,7 @@
 
     // Verify that ContentScriptTracker detected the injection.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 
   // Add a new subframe with a `data:...` URL.  This will verify that the
@@ -487,7 +487,7 @@
 
     // Verify that content script has been injected.
     ASSERT_TRUE(listener.WaitUntilSatisfied());
-    content::RenderFrameHost* main_frame = first_tab->GetMainFrame();
+    content::RenderFrameHost* main_frame = first_tab->GetPrimaryMainFrame();
     content::RenderFrameHost* child_frame =
         content::ChildFrameAt(main_frame, 0);
     ASSERT_TRUE(child_frame);
@@ -554,7 +554,7 @@
 
     // Verify that ContentScriptTracker properly covered the initial frame.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 
   // Open a new tab with 'about:blank'.  This may be tricky, because the initial
@@ -579,9 +579,9 @@
     // same process, but this kind of verification is important if we ever
     // consider going back to per-frame tracking.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *popup->GetMainFrame()->GetProcess(), extension->id()));
+        *popup->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 }
 
@@ -649,7 +649,7 @@
 
     // Verify that ContentScriptTracker properly covered the initial frame.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 
   // Add a new subframe with `src=javascript:...` attribute.  This will leave
@@ -672,7 +672,7 @@
 
   // Verify expected properties of the test scenario - the `child_frame` should
   // have stayed at the initial empty document.
-  content::RenderFrameHost* main_frame = first_tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = first_tab->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = content::ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(child_frame);
   EXPECT_EQ(main_frame->GetLastCommittedOrigin().Serialize(),
@@ -906,7 +906,7 @@
 
   // MAIN VERIFICATION: Verify that ContentScriptTracker detected the injection.
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *web_contents->GetMainFrame()->GetProcess(), extension->id()));
+      *web_contents->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 }
 
 // Tests tracking of content scripts injected/declared via
@@ -970,7 +970,7 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 
   // Navigate to a test page that *is* covered by the PageStateMatcher above.
   {
@@ -991,14 +991,14 @@
 
     // Verify that ContentScriptTracker detected the injection.
     EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-        *second_tab->GetMainFrame()->GetProcess(), extension->id()));
+        *second_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   }
 
   // Verify that still no content script has been run in the `first_tab`.
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 #endif  // BUILDFLAG(IS_MAC)
 }
 
@@ -1035,8 +1035,10 @@
 
   // Verify that content script has been injected.
   ASSERT_TRUE(listener.WaitUntilSatisfied());
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   EXPECT_EQ("content script has run",
             content::EvalJs(main_frame, "document.body.innerText"));
 
@@ -1110,7 +1112,7 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 
   // Navigate to a test page that *is* covered by the dynamic content script
   // above.
@@ -1125,8 +1127,8 @@
   content::WebContents* second_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_NE(first_tab, second_tab);
-  EXPECT_NE(first_tab->GetMainFrame()->GetProcess(),
-            second_tab->GetMainFrame()->GetProcess());
+  EXPECT_NE(first_tab->GetPrimaryMainFrame()->GetProcess(),
+            second_tab->GetPrimaryMainFrame()->GetProcess());
 
   // Verify that the new tab shows up as having been injected with content
   // scripts.
@@ -1135,9 +1137,9 @@
   EXPECT_EQ("This page has no title.",
             content::EvalJs(first_tab, "document.body.innerText"));
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *second_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *second_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
-      *first_tab->GetMainFrame()->GetProcess(), extension->id()));
+      *first_tab->GetPrimaryMainFrame()->GetProcess(), extension->id()));
 }
 
 class ContentScriptTrackerAppBrowserTest : public PlatformAppBrowserTest {
@@ -1233,7 +1235,7 @@
   // Verify that ContentScriptTracker correctly shows that no content scripts
   // got injected just yet.
   content::RenderProcessHost* guest_process =
-      guest_contents->GetMainFrame()->GetProcess();
+      guest_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *guest_process, app->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
@@ -1280,7 +1282,7 @@
   // Verify that ContentScriptTracker detected the content script injection
   // from `app` in the bar.com guest process (but not from
   // `unrelated_extension`).
-  guest_process = guest_contents->GetMainFrame()->GetProcess();
+  guest_process = guest_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_TRUE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *guest_process, app->id()));
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
@@ -1353,7 +1355,7 @@
   // Verify that ContentScriptTracker correctly shows that no content scripts
   // got injected just yet.
   content::RenderProcessHost* guest_process =
-      guest_contents->GetMainFrame()->GetProcess();
+      guest_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_FALSE(ContentScriptTracker::DidProcessRunContentScriptFromExtension(
       *guest_process, app->id()));
 
diff --git a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
index abd08895..574f9e8e 100644
--- a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
+++ b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
@@ -587,10 +587,12 @@
     // the |content_script| declared in the extension manifest.
     GURL page_url = GetTestPageUrl("fetch-initiator.com");
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-    EXPECT_EQ(page_url,
-              active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-    EXPECT_EQ(url::Origin::Create(page_url),
-              active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+    EXPECT_EQ(
+        page_url,
+        active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+    EXPECT_EQ(
+        url::Origin::Create(page_url),
+        active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
     // Extract results of the fetch done in the declarative content script.
     std::string fetch_result = PopString(&message_queue);
@@ -641,10 +643,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com.
@@ -673,10 +677,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that adds a link that initiates a fetch from
   // cross-site.com.
@@ -768,10 +774,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Test fetch from a host allowed by the policy (and allowed by the extension
   // permissions).
@@ -824,10 +832,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Test fetch from a host allowed by the policy (and allowed by the extension
   // permissions).
@@ -873,10 +883,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com.
@@ -920,8 +932,9 @@
 
   // Navigate to a file:// test page.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
   const char kScriptTemplate[] = R"(
       const url = $1;
       const xhr = new XMLHttpRequest();
@@ -998,10 +1011,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Verify behavior for fetching URLs covered by extension permissions.
   GURL kAllowedUrls[] = {
@@ -1036,10 +1051,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com.
@@ -1070,10 +1087,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // other-without-permission.com.
@@ -1099,10 +1118,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // other-without-permission.com.
@@ -1135,10 +1156,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a same-origin fetch to
   // fetch-initiator.com.
@@ -1163,10 +1186,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com.
@@ -1250,7 +1275,7 @@
     return;
   SimulateNetworkServiceCrash();
   active_web_contents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->FlushNetworkAndNavigationInterfacesForTesting();
   {
     content::DOMMessageQueue message_queue(active_web_contents());
@@ -1279,10 +1304,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Verify behavior for fetching URLs covered by extension permissions.
   GURL kAllowedUrls[] = {
@@ -1316,10 +1343,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com (to a PNG image that is incorrectly labelled as
@@ -1346,10 +1375,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin fetch to
   // cross-site.com.
@@ -1613,8 +1644,10 @@
   // Navigate a tab to the extension origin.
   GURL extension_resource = GetExtensionResource("page.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), extension_resource));
-  content::RenderFrameHost* test_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* test_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   ASSERT_EQ(GetExtensionOrigin(), test_frame->GetLastCommittedOrigin());
 
   // Perform a cross-origin fetch from an extension frame and verify that it got
@@ -1704,11 +1737,13 @@
       ASSERT_EQ(extension_resource, navigation_observer.last_navigation_url());
     }
   }
-  content::RenderFrameHost* regular_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* regular_frame = browser()
+                                                ->tab_strip_model()
+                                                ->GetActiveWebContents()
+                                                ->GetPrimaryMainFrame();
   ASSERT_EQ(GetExtensionOrigin(), regular_frame->GetLastCommittedOrigin());
   content::RenderFrameHost* incognito_frame =
-      content::ChildFrameAt(incognito_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(incognito_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(incognito_frame);
   ASSERT_EQ(GetExtensionOrigin(), incognito_frame->GetLastCommittedOrigin());
 
@@ -1789,9 +1824,10 @@
   content::WebContents* incognito_contents =
       incognito_browser->tab_strip_model()->GetActiveWebContents();
   ASSERT_EQ(extension->origin(),
-            regular_contents->GetMainFrame()->GetLastCommittedOrigin());
-  ASSERT_EQ(extension->origin(),
-            incognito_contents->GetMainFrame()->GetLastCommittedOrigin());
+            regular_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      extension->origin(),
+      incognito_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Test fetching a cross-site resource.
   GURL cross_site_resource(
@@ -1857,8 +1893,9 @@
   // Navigate a tab to an extension page.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
                                            GetExtensionResource("page.html")));
-  ASSERT_EQ(GetExtensionOrigin(),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      GetExtensionOrigin(),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Verify that the service worker controls the fetches.
   bool is_controlled_by_service_worker = false;
@@ -2067,8 +2104,9 @@
     //    (task posted from ReadyToCommitNavigation above should execute
     //     before any IPC responses that come after PostTask call).
     ready_to_commit_waiter.Wait();
-    DCHECK_NE(web_ui_url,
-              active_web_contents()->GetMainFrame()->GetLastCommittedURL());
+    DCHECK_NE(
+        web_ui_url,
+        active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
 
     // Inject the content script (simulating chrome.tabs.executeScript, but
     // using TabsExecuteScriptFunction directly to ensure the right timing).
@@ -2093,8 +2131,9 @@
 
     // Wait until the navigation completes.
     navigation_observer.Wait();
-    EXPECT_EQ(web_ui_url,
-              active_web_contents()->GetMainFrame()->GetLastCommittedURL());
+    EXPECT_EQ(
+        web_ui_url,
+        active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
   }
 
   // Check if the injection above succeeded (it shouldn't have, because of
@@ -2232,10 +2271,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin GET fetch to
   // cross-site.com.
@@ -2279,10 +2320,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin POST fetch to
   // cross-site.com.
@@ -2323,10 +2366,12 @@
   // Navigate to a fetch-initiator.com page.
   GURL page_url = GetTestPageUrl("fetch-initiator.com");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a same-origin POST fetch to
   // fetch-initiator.com.
@@ -2373,10 +2418,12 @@
   // Navigate to https test page.
   GURL page_url = https_server.GetURL("/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a same-origin GET fetch.
   GURL same_origin_resource(https_server.GetURL("/subresource"));
@@ -2414,10 +2461,12 @@
   // Navigate to https test page.
   GURL page_url = https_server.GetURL("/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(url::Origin::Create(page_url),
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      url::Origin::Create(page_url),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a same-origin GET XHR.
   GURL same_origin_resource(https_server.GetURL("/subresource"));
@@ -2452,10 +2501,12 @@
   url::Origin page_origin = url::Origin::Create(page_url);
   std::string page_origin_string = page_origin.Serialize();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-  ASSERT_EQ(page_url,
-            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
-  ASSERT_EQ(page_origin,
-            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+  ASSERT_EQ(
+      page_url,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
+  ASSERT_EQ(
+      page_origin,
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Inject a content script that performs a cross-origin GET fetch.
   content::DOMMessageQueue message_queue(active_web_contents());
@@ -2803,8 +2854,9 @@
   // background page).
   content::WebContents* regular_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(kRegularHost,
-            regular_contents->GetMainFrame()->GetLastCommittedOrigin().host());
+  EXPECT_EQ(
+      kRegularHost,
+      regular_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().host());
   EXPECT_NE(kRegularHost, kIncognitoHost);
   ExtensionActionRunner::GetForWebContents(regular_contents)
       ->RunAction(extension, true);
diff --git a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
index 62b8ee4f..112f513 100644
--- a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
+++ b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
@@ -288,8 +288,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), extension_test_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(IsCrossOriginIsolated(web_contents->GetMainFrame()));
-  EXPECT_EQ(web_contents->GetMainFrame()->GetProcess(),
+  EXPECT_TRUE(IsCrossOriginIsolated(web_contents->GetPrimaryMainFrame()));
+  EXPECT_EQ(web_contents->GetPrimaryMainFrame()->GetProcess(),
             coi_background_rfh->GetProcess());
 
   // Load test.html as a web accessible resource inside a web frame.
@@ -299,7 +299,7 @@
       content::NavigateIframeToURL(web_contents, "test", extension_test_url));
 
   content::RenderFrameHost* extension_iframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(extension_iframe);
   EXPECT_EQ(extension_test_url, extension_iframe->GetLastCommittedURL());
 
@@ -309,7 +309,7 @@
   EXPECT_FALSE(IsCrossOriginIsolated(extension_iframe));
   EXPECT_NE(extension_iframe->GetProcess(), coi_background_rfh->GetProcess());
   EXPECT_NE(extension_iframe->GetProcess(),
-            web_contents->GetMainFrame()->GetProcess());
+            web_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Check ProcessManager APIs to ensure they work correctly for the case where
   // an extension has multiple processes for the same profile.
@@ -482,7 +482,7 @@
   ASSERT_TRUE(
       content::NavigateIframeToURL(web_contents, "test", extension_test_url));
   content::RenderFrameHost* extension_iframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(extension_iframe);
 
   content::RenderFrameHost* extension_tab =
@@ -591,7 +591,7 @@
   ASSERT_TRUE(
       content::NavigateIframeToURL(web_contents, "test", extension_test_url));
   content::RenderFrameHost* extension_iframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(extension_iframe);
 
   content::RenderFrameHost* extension_tab =
diff --git a/chrome/browser/extensions/dynamic_origin_browsertest.cc b/chrome/browser/extensions/dynamic_origin_browsertest.cc
index f83a212..43c432e8 100644
--- a/chrome/browser/extensions/dynamic_origin_browsertest.cc
+++ b/chrome/browser/extensions/dynamic_origin_browsertest.cc
@@ -37,8 +37,8 @@
     return browser()->tab_strip_model()->GetActiveWebContents();
   }
 
-  content::RenderFrameHost* GetMainFrame() const {
-    return GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame() const {
+    return GetActiveWebContents()->GetPrimaryMainFrame();
   }
 
  private:
@@ -75,7 +75,8 @@
   {
     ASSERT_TRUE(ui_test_utils::NavigateToURL(
         browser(), extension->GetResourceURL("ok.html")));
-    ASSERT_EQ(extension->origin(), GetMainFrame()->GetLastCommittedOrigin());
+    ASSERT_EQ(extension->origin(),
+              GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
 
   // Dynamic resource should resolve to static url.
@@ -84,8 +85,9 @@
     GURL dynamic_url = extension->dynamic_url().Resolve("ok.html");
     ASSERT_NE(static_url, dynamic_url);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), dynamic_url));
-    EXPECT_EQ(static_url, GetMainFrame()->GetLastCommittedURL());
-    EXPECT_EQ(extension->origin(), GetMainFrame()->GetLastCommittedOrigin());
+    EXPECT_EQ(static_url, GetPrimaryMainFrame()->GetLastCommittedURL());
+    EXPECT_EQ(extension->origin(),
+              GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
 }
 
@@ -129,7 +131,7 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), frame_url));
     content::WebContents* web_contents = GetActiveWebContents();
     EXPECT_EQ(expected_frame_url,
-              web_contents->GetMainFrame()->GetLastCommittedURL());
+              web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
     std::string result;
     constexpr char kFetchScriptTemplate[] =
diff --git a/chrome/browser/extensions/extension_action_runner_browsertest.cc b/chrome/browser/extensions/extension_action_runner_browsertest.cc
index 2da7c63..51d9464 100644
--- a/chrome/browser/extensions/extension_action_runner_browsertest.cc
+++ b/chrome/browser/extensions/extension_action_runner_browsertest.cc
@@ -589,8 +589,8 @@
   // Create a fenced frame and load the test url. Active extensions should not
   // be cleared by the fenced frame navigation.
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_helper_.CreateFencedFrame(web_contents->GetMainFrame(),
-                                             fenced_frame_url);
+      fenced_frame_helper_.CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
   EXPECT_EQ(active_tab_granter->granted_extensions_.size(), 1U);
 
@@ -630,8 +630,8 @@
   GURL fenced_frame_url =
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_helper_.CreateFencedFrame(web_contents->GetMainFrame(),
-                                             fenced_frame_url);
+      fenced_frame_helper_.CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
   // Fenced frame doesn't clear pending script injection requests and the
   // scripts.
diff --git a/chrome/browser/extensions/extension_bindings_apitest.cc b/chrome/browser/extensions/extension_bindings_apitest.cc
index ff83bcf..1f5c1fe 100644
--- a/chrome/browser/extensions/extension_bindings_apitest.cc
+++ b/chrome/browser/extensions/extension_bindings_apitest.cc
@@ -43,7 +43,7 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(10, 10);
   mouse_event.click_count = 1;
-  web_contents->GetMainFrame()
+  web_contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardMouseEvent(mouse_event);
@@ -56,7 +56,7 @@
   mouse_event.button = blink::WebMouseEvent::Button::kLeft;
   mouse_event.SetPositionInWidget(10, 10);
   mouse_event.click_count = 1;
-  web_contents->GetMainFrame()
+  web_contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardMouseEvent(mouse_event);
@@ -412,7 +412,7 @@
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* subframe = ChildFrameAt(main_frame, 0);
   content::RenderFrameDeletedObserver subframe_deleted(subframe);
 
diff --git a/chrome/browser/extensions/extension_browser_window_helper.cc b/chrome/browser/extensions/extension_browser_window_helper.cc
index 0e8c88c7..cc3b813f 100644
--- a/chrome/browser/extensions/extension_browser_window_helper.cc
+++ b/chrome/browser/extensions/extension_browser_window_helper.cc
@@ -32,7 +32,7 @@
   // windows with opaque origins that were opened by extensions, and may
   // still be running code.
   const url::SchemeHostPort& tuple_or_precursor_tuple =
-      web_contents->GetMainFrame()
+      web_contents->GetPrimaryMainFrame()
           ->GetLastCommittedOrigin()
           .GetTupleOrPrecursorTupleIfOpaque();
   if (tuple_or_precursor_tuple.scheme() == extensions::kExtensionScheme &&
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index be7408e..ef61d25 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -787,11 +787,11 @@
   }
 
   if (newtab_process_should_equal_opener) {
-    EXPECT_EQ(contents->GetMainFrame()->GetSiteInstance(),
-              newtab->GetMainFrame()->GetSiteInstance());
+    EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance(),
+              newtab->GetPrimaryMainFrame()->GetSiteInstance());
   } else {
-    EXPECT_NE(contents->GetMainFrame()->GetSiteInstance(),
-              newtab->GetMainFrame()->GetSiteInstance());
+    EXPECT_NE(contents->GetPrimaryMainFrame()->GetSiteInstance(),
+              newtab->GetPrimaryMainFrame()->GetSiteInstance());
   }
 
   if (newtab_result)
diff --git a/chrome/browser/extensions/extension_cookies_browsertest.cc b/chrome/browser/extensions/extension_cookies_browsertest.cc
index f95a30d..b9e113c 100644
--- a/chrome/browser/extensions/extension_cookies_browsertest.cc
+++ b/chrome/browser/extensions/extension_cookies_browsertest.cc
@@ -149,7 +149,7 @@
   content::RenderFrameHost* NavigateMainFrameToExtensionPage() {
     EXPECT_TRUE(content::NavigateToURL(
         web_contents(), extension_->GetResourceURL("/empty.html")));
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   // Appends a child iframe via JS and waits for it to load. Returns a pointer
@@ -653,7 +653,7 @@
       ProcessManager::Get(profile())
           ->GetBackgroundHostForExtension(extension->id())
           ->host_contents()
-          ->GetMainFrame();
+          ->GetPrimaryMainFrame();
 
   // Set up a test scenario:
   // - top-level frame: kActiveTabHost
@@ -879,8 +879,9 @@
   GURL original_document_url =
       test_server()->GetURL(kActiveTabHost, "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), original_document_url));
-  EXPECT_EQ(kActiveTabHost,
-            web_contents()->GetMainFrame()->GetLastCommittedURL().host());
+  EXPECT_EQ(
+      kActiveTabHost,
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL().host());
   SetCookies(kActiveTabHost);
   GURL extension_frame_url = extension->GetResourceURL("frame.html");
   ui_test_utils::NavigateToURLWithDisposition(
@@ -888,7 +889,7 @@
       ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP |
           ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   content::RenderFrameHost* extension_frame =
-      browser()->tab_strip_model()->GetWebContentsAt(1)->GetMainFrame();
+      browser()->tab_strip_model()->GetWebContentsAt(1)->GetPrimaryMainFrame();
   EXPECT_EQ(extension_frame_url, extension_frame->GetLastCommittedURL());
 
   // Based on activeTab, the extension shouldn't be initially granted access to
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
index 5f40896..f537762 100644
--- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
+++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -98,8 +98,9 @@
     ASSERT_TRUE(extension_host);
     extensions::ProcessManager::FrameSet frames =
         GetProcessManager()->GetAllFrames();
-    ASSERT_NE(frames.end(),
-              frames.find(extension_host->host_contents()->GetMainFrame()));
+    ASSERT_NE(
+        frames.end(),
+        frames.find(extension_host->host_contents()->GetPrimaryMainFrame()));
     ASSERT_FALSE(GetProcessManager()->GetAllFrames().empty());
     ASSERT_TRUE(extension_host->IsRendererLive());
     extensions::ProcessMap* process_map =
diff --git a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
index 1b54fe7a9..c4e8d0ad 100644
--- a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
+++ b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
@@ -85,7 +85,7 @@
   }
 
   bool CanLoadScript(const Extension* extension) {
-    content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+    content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame();
     std::string code = base::StringPrintf(
         R"(
         var s = document.createElement('script');
@@ -222,7 +222,7 @@
 
   // The iframe must be blocked because of CSP.
   console_observer.Wait();
-  content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
   EXPECT_EQ(popup_url, main_frame->GetLastCommittedURL());
   EXPECT_EQ(iframe_url, child_frame->GetLastCommittedURL());
diff --git a/chrome/browser/extensions/extension_functional_browsertest.cc b/chrome/browser/extensions/extension_functional_browsertest.cc
index fbfa220f..64bacf8 100644
--- a/chrome/browser/extensions/extension_functional_browsertest.cc
+++ b/chrome/browser/extensions/extension_functional_browsertest.cc
@@ -109,9 +109,9 @@
   // Sanity-check test setup: 2 frames share a renderer process, but are not in
   // a related browsing instance.
   content::RenderFrameHost* tab1 =
-      browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame();
+      browser()->tab_strip_model()->GetWebContentsAt(0)->GetPrimaryMainFrame();
   content::RenderFrameHost* tab2 =
-      browser()->tab_strip_model()->GetWebContentsAt(1)->GetMainFrame();
+      browser()->tab_strip_model()->GetWebContentsAt(1)->GetPrimaryMainFrame();
   EXPECT_EQ(tab1->GetProcess(), tab2->GetProcess());
   EXPECT_FALSE(
       tab1->GetSiteInstance()->IsRelatedSiteInstance(tab2->GetSiteInstance()));
@@ -133,7 +133,7 @@
     ASSERT_TRUE(did_create_popup);
     content::WebContents* popup_window = new_window_observer.GetWebContents();
     EXPECT_TRUE(WaitForLoadStop(popup_window));
-    tab1_popup = popup_window->GetMainFrame();
+    tab1_popup = popup_window->GetPrimaryMainFrame();
   }
   EXPECT_EQ(GURL(url::kAboutBlankURL), tab1_popup->GetLastCommittedURL());
 
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc
index ceafc60..9ed999f5 100644
--- a/chrome/browser/extensions/extension_nacl_browsertest.cc
+++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -259,7 +259,8 @@
   // Sanity check - the test setup should cause main frame and subframe to be in
   // a different process.
   content::RenderFrameHost* subframe = ChildFrameAt(web_contents, 0);
-  EXPECT_NE(web_contents->GetMainFrame()->GetProcess(), subframe->GetProcess());
+  EXPECT_NE(web_contents->GetPrimaryMainFrame()->GetProcess(),
+            subframe->GetProcess());
 
   // Insert a plugin element into the subframe.  Before the fix from
   // https://crrev.com/2932703005 this would have trigerred a crash reported in
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc
index 277c9990..0bc1239 100644
--- a/chrome/browser/extensions/extension_protocols_unittest.cc
+++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -353,7 +353,7 @@
   content::WebContents* web_contents() { return contents_.get(); }
 
   content::RenderFrameHost* main_rfh() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
index 40a70e0..00ddc58 100644
--- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -338,7 +338,7 @@
   GURL accessible_url = extension->GetResourceURL("/test.png");
   EXPECT_EQ(accessible_url, result);
   EXPECT_EQ(accessible_url,
-            web_contents->GetMainFrame()->GetLastCommittedURL());
+            web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   GURL nonaccessible_linked_resource(embedded_test_server()->GetURL(
       "/extensions/api_test/extension_resource_request_policy/"
@@ -352,7 +352,8 @@
             controller.GetLastCommittedEntry()->GetPageType());
   EXPECT_EQ("chrome-error://chromewebdata/", result);
   GURL invalid_url("chrome-extension://invalid/");
-  EXPECT_EQ(invalid_url, web_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(invalid_url,
+            web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   // Redirects can sometimes occur before the load event, so use a
   // UrlLoadObserver instead of blocking waiting for two load events.
@@ -434,7 +435,7 @@
   EXPECT_NE(private_page, web_contents->GetLastCommittedURL());
   std::string content;
   EXPECT_TRUE(ExecuteScriptAndExtractString(
-      ChildFrameAt(web_contents->GetMainFrame(), 0),
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0),
       "domAutomationController.send(document.body.innerText)", &content));
 
   // The iframe should not load |private_page|, which is not web-accessible.
@@ -478,7 +479,7 @@
 
   // That should not have been allowed.
   EXPECT_NE(url::Origin::Create(target_url).GetURL(),
-            ChildFrameAt(web_contents->GetMainFrame(), 0)
+            ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0)
                 ->GetLastCommittedOrigin()
                 .GetURL());
 }
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
index d4c4c8fc..19c9c52 100644
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
@@ -289,11 +289,13 @@
     // RenderProcessHost on all platforms.)
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    int old_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+    int old_process_id =
+        web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
     EXPECT_TRUE(
         ui_test_utils::NavigateToURL(browser(), GURL("chrome://version")));
     EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
-    int new_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+    int new_process_id =
+        web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
     EXPECT_NE(old_process_id, new_process_id);
 
     // Only intercept messages from `active_extension`'s content script running
@@ -355,7 +357,7 @@
   // Inject the malformed/mutated IPC and verify that the renderer is terminated
   // as expected.
   content::RenderProcessHost* main_frame_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
   IPC::IpcSecurityTestUtil::PwnMessageReceived(
       main_frame_process->GetChannel(),
@@ -386,7 +388,7 @@
   // Inject the malformed/mutated IPC and verify that the renderer is terminated
   // as expected.
   content::RenderProcessHost* main_frame_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
   IPC::IpcSecurityTestUtil::PwnMessageReceived(
       main_frame_process->GetChannel(),
@@ -416,7 +418,7 @@
   // Inject the malformed/mutated IPC and verify that the renderer is terminated
   // as expected.
   content::RenderProcessHost* main_frame_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
   IPC::IpcSecurityTestUtil::PwnMessageReceived(
       main_frame_process->GetChannel(),
@@ -448,7 +450,7 @@
   // Inject the malformed/mutated IPC and verify that the renderer is terminated
   // as expected.
   content::RenderProcessHost* main_frame_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
   IPC::IpcSecurityTestUtil::PwnMessageReceived(
       main_frame_process->GetChannel(),
@@ -482,7 +484,7 @@
   // Inject the malformed/mutated IPC and verify that the renderer is terminated
   // as expected.
   content::RenderProcessHost* main_frame_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
   IPC::IpcSecurityTestUtil::PwnMessageReceived(
       main_frame_process->GetChannel(),
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
index e5ad4ae..dab2f98 100644
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -154,7 +154,7 @@
 }
 
 bool HasValidMainFrameProcess(content::WebContents* contents) {
-  content::RenderFrameHost* main_frame_host = contents->GetMainFrame();
+  content::RenderFrameHost* main_frame_host = contents->GetPrimaryMainFrame();
   content::RenderProcessHost* process_host = main_frame_host->GetProcess();
   return process_host->IsReady() && process_host->IsInitializedAndNotDead();
 }
diff --git a/chrome/browser/extensions/extension_unload_browsertest.cc b/chrome/browser/extensions/extension_unload_browsertest.cc
index 0362190..8959a02 100644
--- a/chrome/browser/extensions/extension_unload_browsertest.cc
+++ b/chrome/browser/extensions/extension_unload_browsertest.cc
@@ -146,7 +146,7 @@
   EXPECT_TRUE(browser()
                   ->tab_strip_model()
                   ->GetActiveWebContents()
-                  ->GetMainFrame()
+                  ->GetPrimaryMainFrame()
                   ->IsRenderFrameLive());
 }
 
@@ -179,7 +179,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(about_blank, web_contents->GetLastCommittedURL());
   url::Origin frame_origin =
-      web_contents->GetMainFrame()->GetLastCommittedOrigin();
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   url::SchemeHostPort precursor_tuple =
       frame_origin.GetTupleOrPrecursorTupleIfOpaque();
   EXPECT_EQ(kExtensionScheme, precursor_tuple.scheme());
@@ -220,7 +220,7 @@
 
   {
     content::ScopedAllowRendererCrashes allow_renderer_crashes(
-        active_tab->GetMainFrame()->GetProcess());
+        active_tab->GetPrimaryMainFrame()->GetProcess());
     ui_test_utils::NavigateToURLWithDisposition(
         browser(), GURL("chrome://crash"), WindowOpenDisposition::CURRENT_TAB,
         ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
diff --git a/chrome/browser/extensions/extension_untrusted_webui_apitest.cc b/chrome/browser/extensions/extension_untrusted_webui_apitest.cc
index 5491c1d..88363ae 100644
--- a/chrome/browser/extensions/extension_untrusted_webui_apitest.cc
+++ b/chrome/browser/extensions/extension_untrusted_webui_apitest.cc
@@ -58,8 +58,10 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(
         browser(), GURL("chrome-untrusted://api-test/title1.html")));
 
-    content::RenderFrameHost* rfh =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* rfh = browser()
+                                        ->tab_strip_model()
+                                        ->GetActiveWebContents()
+                                        ->GetPrimaryMainFrame();
     ASSERT_TRUE(rfh);
     content::ExecuteScriptAsync(rfh, script);
 
diff --git a/chrome/browser/extensions/extension_view_host.cc b/chrome/browser/extensions/extension_view_host.cc
index c7580bf..6aa6879 100644
--- a/chrome/browser/extensions/extension_view_host.cc
+++ b/chrome/browser/extensions/extension_view_host.cc
@@ -67,11 +67,11 @@
     content::HostZoomMap* zoom_map =
         content::HostZoomMap::GetForWebContents(host_contents());
     zoom_map->SetTemporaryZoomLevel(
+        host_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
         host_contents()
-            ->GetMainFrame()
-            ->GetProcess()
-            ->GetID(),
-        host_contents()->GetMainFrame()->GetRenderViewHost()->GetRoutingID(),
+            ->GetPrimaryMainFrame()
+            ->GetRenderViewHost()
+            ->GetRoutingID(),
         zoom_map->GetDefaultZoomLevel());
   }
 }
diff --git a/chrome/browser/extensions/extension_webui_apitest.cc b/chrome/browser/extensions/extension_webui_apitest.cc
index dc688d47..c3b6bdf4 100644
--- a/chrome/browser/extensions/extension_webui_apitest.cc
+++ b/chrome/browser/extensions/extension_webui_apitest.cc
@@ -62,8 +62,10 @@
     // Run the test.
     bool actual_result = false;
     EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), page_url));
-    content::RenderFrameHost* webui =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* webui = browser()
+                                          ->tab_strip_model()
+                                          ->GetActiveWebContents()
+                                          ->GetPrimaryMainFrame();
     if (!webui)
       return testing::AssertionFailure() << "Failed to navigate to WebUI";
     CHECK(content::ExecuteScriptAndExtractBool(webui, script, &actual_result));
@@ -363,7 +365,7 @@
                                            GURL("chrome://test/body1.html")));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   EventRouter* event_router = EventRouter::Get(profile());
   EXPECT_FALSE(event_router->HasEventListener("test.onMessage"));
   // Register a listener and create a child frame at a different URL.
diff --git a/chrome/browser/extensions/isolated_app_browsertest.cc b/chrome/browser/extensions/isolated_app_browsertest.cc
index 0418a38f..226c217 100644
--- a/chrome/browser/extensions/isolated_app_browsertest.cc
+++ b/chrome/browser/extensions/isolated_app_browsertest.cc
@@ -119,7 +119,7 @@
     std::set<std::string> extension_ids =
         ProcessMap::Get(browser_context)
             ->GetExtensionsInProcess(
-                contents->GetMainFrame()->GetProcess()->GetID());
+                contents->GetPrimaryMainFrame()->GetProcess()->GetID());
     for (auto iter = extension_ids.begin(); iter != extension_ids.end();
          ++iter) {
       const Extension* installed_app =
@@ -477,26 +477,26 @@
   int process_id_0 = browser()
                          ->tab_strip_model()
                          ->GetWebContentsAt(0)
-                         ->GetMainFrame()
+                         ->GetPrimaryMainFrame()
                          ->GetProcess()
                          ->GetID();
   int process_id_1 = browser()
                          ->tab_strip_model()
                          ->GetWebContentsAt(1)
-                         ->GetMainFrame()
+                         ->GetPrimaryMainFrame()
                          ->GetProcess()
                          ->GetID();
   EXPECT_NE(process_id_0, process_id_1);
   EXPECT_EQ(process_id_0, browser()
                               ->tab_strip_model()
                               ->GetWebContentsAt(2)
-                              ->GetMainFrame()
+                              ->GetPrimaryMainFrame()
                               ->GetProcess()
                               ->GetID());
   EXPECT_EQ(process_id_0, browser()
                               ->tab_strip_model()
                               ->GetWebContentsAt(3)
-                              ->GetMainFrame()
+                              ->GetPrimaryMainFrame()
                               ->GetProcess()
                               ->GetID());
 
@@ -507,7 +507,7 @@
   EXPECT_NE(process_id_1, browser()
                               ->tab_strip_model()
                               ->GetWebContentsAt(1)
-                              ->GetMainFrame()
+                              ->GetPrimaryMainFrame()
                               ->GetProcess()
                               ->GetID());
 }
diff --git a/chrome/browser/extensions/navigation_observer_browsertest.cc b/chrome/browser/extensions/navigation_observer_browsertest.cc
index 65244c1..7f60a80 100644
--- a/chrome/browser/extensions/navigation_observer_browsertest.cc
+++ b/chrome/browser/extensions/navigation_observer_browsertest.cc
@@ -172,11 +172,12 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(web_contents->GetMainFrame()->GetLastCommittedURL(), main_url);
+  EXPECT_EQ(web_contents->GetPrimaryMainFrame()->GetLastCommittedURL(),
+            main_url);
 
   // Emulate a user gesture so that the current entry won't be skipped due to
   // the history manipulation intervention when we try to navigate back to it.
-  web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
       std::u16string(), base::NullCallback());
 
   // Navigate subframe to an enabled extension URL.
@@ -188,7 +189,7 @@
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", extension_url));
 
   content::RenderFrameHost* subframe =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(subframe->GetLastCommittedURL(), extension_url);
   EXPECT_EQ(web_contents->GetController().GetEntryCount(), 3);
   scoped_refptr<content::SiteInstance> extension_site_instance =
@@ -218,7 +219,7 @@
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
   EXPECT_EQ(web_contents->GetController().GetLastCommittedEntryIndex(), 2);
 
-  subframe = ChildFrameAt(web_contents->GetMainFrame(), 0);
+  subframe = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(subframe->GetLastCommittedURL(), extension_url);
 
   // The SiteInstance of the disabled extension frame should be different from
@@ -249,7 +250,7 @@
   // terminate the renderer and should go back to the original extension
   // SiteInstance.
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", extension_url));
-  subframe = ChildFrameAt(web_contents->GetMainFrame(), 0);
+  subframe = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(subframe->IsRenderFrameLive());
   EXPECT_EQ(subframe->GetSiteInstance(), extension_site_instance);
   EXPECT_TRUE(subframe->GetProcess()->IsProcessLockedToSiteForTesting());
diff --git a/chrome/browser/extensions/omnibox_focus_interactive_test.cc b/chrome/browser/extensions/omnibox_focus_interactive_test.cc
index 8d636f7..ef987d1 100644
--- a/chrome/browser/extensions/omnibox_focus_interactive_test.cc
+++ b/chrome/browser/extensions/omnibox_focus_interactive_test.cc
@@ -122,7 +122,7 @@
   GURL replaced_url = embedded_test_server()->GetURL("/replacement");
   {
     content::TestFrameNavigationObserver nav_observer(
-        web_contents->GetMainFrame());
+        web_contents->GetPrimaryMainFrame());
     ASSERT_TRUE(content::ExecJs(
         web_contents, "history.replaceState({}, '', '/replacement');"));
     nav_observer.Wait();
@@ -173,7 +173,7 @@
       });
   )";
   content::TestFrameNavigationObserver nav_observer(
-      web_contents->GetMainFrame());
+      web_contents->GetPrimaryMainFrame());
   content::ExecuteScriptAsync(
       web_contents, content::JsReplace(kTabsUpdateTemplate, final_ntp_url));
   nav_observer.Wait();
@@ -260,7 +260,7 @@
 
   // pushState
   content::TestFrameNavigationObserver nav_observer(
-      web_contents->GetMainFrame());
+      web_contents->GetPrimaryMainFrame());
   content::ExecuteScriptAsync(web_contents,
                               "history.pushState({}, '', '/push-state')");
   nav_observer.Wait();
@@ -308,7 +308,7 @@
 
   // Execute `location.reload()`.
   content::TestFrameNavigationObserver nav_observer(
-      web_contents->GetMainFrame());
+      web_contents->GetPrimaryMainFrame());
   content::ExecuteScriptAsync(web_contents, "window.location.reload()");
   nav_observer.Wait();
   EXPECT_EQ(1, web_contents->GetController().GetEntryCount());
@@ -357,7 +357,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::TestFrameNavigationObserver nav_observer(
-      web_contents->GetMainFrame());
+      web_contents->GetPrimaryMainFrame());
   ASSERT_TRUE(content::ExecuteScript(
       web_contents, content::JsReplace("window.location = $1", web_url)));
   nav_observer.Wait();
@@ -423,7 +423,7 @@
   // from the main frame.  This ensures that in the next step the navigation
   // will not be triggered by the regular BeginNavigation path, but instead
   // will go through content::RenderFrameProxyHost::OpenURL.
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   EXPECT_NE(subframe->GetLastCommittedURL().scheme(),
             main_frame->GetLastCommittedURL().scheme());
   EXPECT_NE(subframe->GetProcess()->GetID(), main_frame->GetProcess()->GetID());
@@ -440,7 +440,7 @@
   GURL target_url = embedded_test_server()->GetURL("/title2.html");
   {
     content::TestFrameNavigationObserver nav_observer(
-        web_contents->GetMainFrame());
+        web_contents->GetPrimaryMainFrame());
     ASSERT_TRUE(content::ExecuteScript(
         subframe, content::JsReplace(kLinkClickingScriptTemplate, target_url)));
     nav_observer.Wait();
@@ -455,7 +455,7 @@
   // Home button.
   {
     content::TestFrameNavigationObserver nav_observer(
-        web_contents->GetMainFrame());
+        web_contents->GetPrimaryMainFrame());
     chrome::Home(browser(), WindowOpenDisposition::CURRENT_TAB);
     nav_observer.Wait();
   }
@@ -491,7 +491,7 @@
   GURL target_url = embedded_test_server()->GetURL("/title2.html");
   {
     content::TestFrameNavigationObserver nav_observer(
-        web_contents->GetMainFrame());
+        web_contents->GetPrimaryMainFrame());
     ASSERT_TRUE(content::ExecuteScript(
         web_contents,
         content::JsReplace(kLinkClickingScriptTemplate, target_url)));
@@ -507,7 +507,7 @@
   // Home button.
   {
     content::TestFrameNavigationObserver nav_observer(
-        web_contents->GetMainFrame());
+        web_contents->GetPrimaryMainFrame());
     chrome::Home(browser(), WindowOpenDisposition::CURRENT_TAB);
     nav_observer.Wait();
   }
@@ -568,7 +568,7 @@
   GURL fenced_frame_url = https_server().GetURL("/fenced_frames/title1.html");
   content::TestNavigationManager navigation(web_contents, fenced_frame_url);
   EXPECT_TRUE(content::ExecuteScript(
-      web_contents->GetMainFrame(),
+      web_contents->GetPrimaryMainFrame(),
       content::JsReplace(kAddFencedFrameScript, fenced_frame_url)));
   navigation.WaitForNavigationFinished();
 
diff --git a/chrome/browser/extensions/process_management_browsertest.cc b/chrome/browser/extensions/process_management_browsertest.cc
index 384d794..7fff647 100644
--- a/chrome/browser/extensions/process_management_browsertest.cc
+++ b/chrome/browser/extensions/process_management_browsertest.cc
@@ -195,50 +195,51 @@
   content::RenderProcessHost* isolated1_host = browser()
                                                    ->tab_strip_model()
                                                    ->GetWebContentsAt(0)
-                                                   ->GetMainFrame()
+                                                   ->GetPrimaryMainFrame()
                                                    ->GetProcess();
   content::RenderProcessHost* ntp1_host = browser()
                                               ->tab_strip_model()
                                               ->GetWebContentsAt(1)
-                                              ->GetMainFrame()
+                                              ->GetPrimaryMainFrame()
                                               ->GetProcess();
   content::RenderProcessHost* hosted1_host = browser()
                                                  ->tab_strip_model()
                                                  ->GetWebContentsAt(2)
-                                                 ->GetMainFrame()
+                                                 ->GetPrimaryMainFrame()
                                                  ->GetProcess();
   content::RenderProcessHost* web1_host = browser()
                                               ->tab_strip_model()
                                               ->GetWebContentsAt(3)
-                                              ->GetMainFrame()
+                                              ->GetPrimaryMainFrame()
                                               ->GetProcess();
 
   content::RenderProcessHost* isolated2_host = browser()
                                                    ->tab_strip_model()
                                                    ->GetWebContentsAt(4)
-                                                   ->GetMainFrame()
+                                                   ->GetPrimaryMainFrame()
                                                    ->GetProcess();
   content::RenderProcessHost* ntp2_host = browser()
                                               ->tab_strip_model()
                                               ->GetWebContentsAt(5)
-                                              ->GetMainFrame()
+                                              ->GetPrimaryMainFrame()
                                               ->GetProcess();
   content::RenderProcessHost* hosted2_host = browser()
                                                  ->tab_strip_model()
                                                  ->GetWebContentsAt(6)
-                                                 ->GetMainFrame()
+                                                 ->GetPrimaryMainFrame()
                                                  ->GetProcess();
   content::RenderProcessHost* web2_host = browser()
                                               ->tab_strip_model()
                                               ->GetWebContentsAt(7)
-                                              ->GetMainFrame()
+                                              ->GetPrimaryMainFrame()
                                               ->GetProcess();
 
-  content::RenderProcessHost* second_isolated1_host = browser()
-                                                          ->tab_strip_model()
-                                                          ->GetWebContentsAt(8)
-                                                          ->GetMainFrame()
-                                                          ->GetProcess();
+  content::RenderProcessHost* second_isolated1_host =
+      browser()
+          ->tab_strip_model()
+          ->GetWebContentsAt(8)
+          ->GetPrimaryMainFrame()
+          ->GetProcess();
 
   // Get extension processes.
   extensions::ProcessManager* process_manager =
@@ -432,9 +433,12 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   // Verify the number of processes across extensions and tabs.
-  process_ids.insert(web_contents1->GetMainFrame()->GetProcess()->GetID());
-  process_ids.insert(web_contents2->GetMainFrame()->GetProcess()->GetID());
-  process_ids.insert(web_contents3->GetMainFrame()->GetProcess()->GetID());
+  process_ids.insert(
+      web_contents1->GetPrimaryMainFrame()->GetProcess()->GetID());
+  process_ids.insert(
+      web_contents2->GetPrimaryMainFrame()->GetProcess()->GetID());
+  process_ids.insert(
+      web_contents3->GetPrimaryMainFrame()->GetProcess()->GetID());
 
   // The web processes still share 2 processes as if there were a single
   // extension process (making a total of 5 processes counting the existing 3
@@ -456,7 +460,8 @@
       ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
   WebContents* web_contents4 =
       browser()->tab_strip_model()->GetActiveWebContents();
-  process_ids.insert(web_contents4->GetMainFrame()->GetProcess()->GetID());
+  process_ids.insert(
+      web_contents4->GetPrimaryMainFrame()->GetProcess()->GetID());
   // The cross-site process adds 1 more process to the total, to avoid sharing
   // with the existing web renderer processes (due to Site Isolation).
   EXPECT_EQ(6u, process_ids.size());
@@ -478,7 +483,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(extension_url, web_contents->GetLastCommittedURL());
   content::RenderProcessHost* old_process_host =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
 
   // Note that the |setTimeout| call below is needed to make sure
   // ExecuteScriptAndExtractBool returns *after* a scheduled navigation has
@@ -505,7 +510,7 @@
   // Verify that the navigation transferred the contents to another renderer
   // process.
   content::RenderProcessHost* new_process_host =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_NE(old_process_host, new_process_host);
 }
 
@@ -518,7 +523,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(web_url, web_contents->GetLastCommittedURL());
   content::RenderProcessHost* old_process_host =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
 
   // Calculate an URL that is 1) relative to the fake (i.e. test-controlled)
   // Chrome Web Store gallery URL and 2) resolves to something that
@@ -555,7 +560,7 @@
   // Verify that we really have the Chrome Web Store app loaded in the Web
   // Contents.
   content::RenderProcessHost* new_process_host =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_TRUE(extensions::ProcessMap::Get(profile())->Contains(
       extensions::kWebStoreAppId, new_process_host->GetID()));
 
@@ -590,7 +595,7 @@
 
   // Verify that the Chrome Web Store hosted app is really loaded.
   content::RenderProcessHost* render_process_host =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_TRUE(extensions::ProcessMap::Get(profile())->Contains(
       extensions::kWebStoreAppId, render_process_host->GetID()));
 }
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 8f5b135..a0bdb4f2 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -151,8 +151,9 @@
   explicit NavigationCompletedObserver(content::WebContents* web_contents)
       : content::WebContentsObserver(web_contents),
         message_loop_runner_(new content::MessageLoopRunner) {
-    web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-        &AddFrameToSet, base::Unretained(&live_original_frames_)));
+    web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+        base::BindRepeating(&AddFrameToSet,
+                            base::Unretained(&live_original_frames_)));
   }
 
   NavigationCompletedObserver(const NavigationCompletedObserver&) = delete;
@@ -179,7 +180,7 @@
   // this returns false.
   bool AllLiveRenderFrameHostsAreCurrent() {
     std::set<content::RenderFrameHost*> current_frames;
-    web_contents()->GetMainFrame()->ForEachRenderFrameHost(
+    web_contents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
         base::BindRepeating(&AddFrameToSet, base::Unretained(&current_frames)));
 
     return base::STLSetDifference<std::set<content::RenderFrameHost*>>(
@@ -284,7 +285,7 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     WaitForLoadStop(popup);
     if (expect_success)
-      EXPECT_EQ(url, popup->GetMainFrame()->GetLastCommittedURL());
+      EXPECT_EQ(url, popup->GetPrimaryMainFrame()->GetLastCommittedURL());
     return popup;
   }
 
@@ -813,7 +814,7 @@
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
   EXPECT_EQ(1u, pm->GetAllFrames().size());
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0);
 
   // Ideally, this would be a GURL, but it's easier to compose the rest of the
@@ -895,8 +896,8 @@
     // doesn't commit an extension URL or origin.
     EXPECT_NE(nested_urls[i], popup->GetLastCommittedURL());
     EXPECT_FALSE(extension_origin.IsSameOriginWith(
-        popup->GetMainFrame()->GetLastCommittedOrigin()));
-    EXPECT_NE("foo", GetTextContent(popup->GetMainFrame()));
+        popup->GetPrimaryMainFrame()->GetLastCommittedOrigin()));
+    EXPECT_NE("foo", GetTextContent(popup->GetPrimaryMainFrame()));
 
     EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
     EXPECT_EQ(1u, pm->GetAllFrames().size());
@@ -955,7 +956,7 @@
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
   EXPECT_EQ(1u, pm->GetAllFrames().size());
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0);
 
   // Create a valid blob URL in the extension's origin.
@@ -1029,7 +1030,7 @@
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
   EXPECT_EQ(1u, pm->GetAllFrames().size());
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0);
 
   // Create valid blob and filesystem URLs in the extension's origin.
@@ -1082,7 +1083,7 @@
 
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // Create blob and filesystem URLs in the extension's origin.
   url::Origin extension_origin(main_frame->GetLastCommittedOrigin());
@@ -1119,8 +1120,8 @@
 
     EXPECT_EQ(nested_urls[0], popup->GetLastCommittedURL());
     EXPECT_EQ(extension_origin,
-              popup->GetMainFrame()->GetLastCommittedOrigin());
-    EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame()));
+              popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+    EXPECT_EQ("foo", GetTextContent(popup->GetPrimaryMainFrame()));
 
     EXPECT_EQ(3u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
     EXPECT_EQ(3u, pm->GetAllFrames().size());
@@ -1145,8 +1146,8 @@
     // so it's origin will change to the extension URL.
     EXPECT_EQ(GURL(url::kAboutBlankURL), popup->GetLastCommittedURL());
     EXPECT_EQ(extension_origin,
-              popup->GetMainFrame()->GetLastCommittedOrigin());
-    EXPECT_EQ(std::string(), GetTextContent(popup->GetMainFrame()));
+              popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+    EXPECT_EQ(std::string(), GetTextContent(popup->GetPrimaryMainFrame()));
 
     EXPECT_EQ(4u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
     EXPECT_EQ(4u, pm->GetAllFrames().size());
@@ -1186,7 +1187,7 @@
                          ->GetAppWindowsForApp(app->id());
   EXPECT_EQ(1u, app_windows.size());
   content::WebContents* app_tab = (*app_windows.begin())->web_contents();
-  content::RenderFrameHost* app_rfh = app_tab->GetMainFrame();
+  content::RenderFrameHost* app_rfh = app_tab->GetPrimaryMainFrame();
   url::Origin app_origin(app_rfh->GetLastCommittedOrigin());
   EXPECT_EQ(url::Origin::Create(app->url()), app_rfh->GetLastCommittedOrigin());
 
@@ -1217,16 +1218,19 @@
   GURL web_url(embedded_test_server()->GetURL("/title1.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), web_url));
   EXPECT_NE(web_tab, app_tab);
-  EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess());
+  EXPECT_NE(web_tab->GetPrimaryMainFrame()->GetProcess(),
+            app_rfh->GetProcess());
 
   // The web process shouldn't have permission to request URLs in the app's
   // origin, but the guest process should.
   content::ChildProcessSecurityPolicy* policy =
       content::ChildProcessSecurityPolicy::GetInstance();
   EXPECT_FALSE(policy->CanRequestURL(
-      web_tab->GetMainFrame()->GetProcess()->GetID(), app_origin.GetURL()));
-  EXPECT_TRUE(policy->CanRequestURL(
-      guest->GetMainFrame()->GetProcess()->GetID(), app_origin.GetURL()));
+      web_tab->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      app_origin.GetURL()));
+  EXPECT_TRUE(
+      policy->CanRequestURL(guest->GetPrimaryMainFrame()->GetProcess()->GetID(),
+                            app_origin.GetURL()));
 
   // Try navigating the web tab to each nested URL with the app's origin.  This
   // should be blocked.
@@ -1238,9 +1242,10 @@
     observer.Wait();
     EXPECT_NE(nested_urls[i], web_tab->GetLastCommittedURL());
     EXPECT_FALSE(app_origin.IsSameOriginWith(
-        web_tab->GetMainFrame()->GetLastCommittedOrigin()));
-    EXPECT_NE("foo", GetTextContent(web_tab->GetMainFrame()));
-    EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess());
+        web_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin()));
+    EXPECT_NE("foo", GetTextContent(web_tab->GetPrimaryMainFrame()));
+    EXPECT_NE(web_tab->GetPrimaryMainFrame()->GetProcess(),
+              app_rfh->GetProcess());
 
     EXPECT_EQ(2u, pm->GetAllFrames().size());
     EXPECT_EQ(2u, pm->GetRenderFrameHostsForExtension(app->id()).size());
@@ -1265,7 +1270,7 @@
 
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // Have the web page navigate the popup to each nested URL with extension
   // origin via the window reference it obtained earlier from window.open.
@@ -1280,7 +1285,7 @@
     EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
 
     // Create a valid blob or filesystem URL in the extension's origin.
-    GURL nested_url = (*create_function)(popup->GetMainFrame(), "foo");
+    GURL nested_url = (*create_function)(popup->GetPrimaryMainFrame(), "foo");
 
     // Navigate via the proxy to |nested_url|. This should be blocked by
     // FilterURL.
@@ -1291,7 +1296,7 @@
     // Because the navigation was blocked, the URL doesn't change.
     EXPECT_NE(nested_url, popup->GetLastCommittedURL());
     EXPECT_EQ(extension_url, popup->GetLastCommittedURL().spec());
-    EXPECT_NE("foo", GetTextContent(popup->GetMainFrame()));
+    EXPECT_NE("foo", GetTextContent(popup->GetPrimaryMainFrame()));
     EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
     EXPECT_EQ(1u, pm->GetAllFrames().size());
     popup->Close();
@@ -1317,7 +1322,7 @@
 
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // Open a new about:blank popup from main frame.  This should stay in the web
   // process.
@@ -1336,7 +1341,7 @@
   observer.Wait();
   EXPECT_EQ(1u, pm->GetAllFrames().size());
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
-  content::RenderFrameHost* extension_frame = popup->GetMainFrame();
+  content::RenderFrameHost* extension_frame = popup->GetPrimaryMainFrame();
 
   // Create valid blob and filesystem URLs in the extension's origin.
   url::Origin extension_origin(extension_frame->GetLastCommittedOrigin());
@@ -1350,13 +1355,13 @@
   GURL nested_urls[] = {blob_url, filesystem_url};
   for (size_t i = 0; i < std::size(nested_urls); i++) {
     content::WebContents* new_popup =
-        OpenPopupNoOpener(tab->GetMainFrame(), nested_urls[i]);
+        OpenPopupNoOpener(tab->GetPrimaryMainFrame(), nested_urls[i]);
 
     // This is a top-level navigation to a local resource, that should be
     // blocked by FilterURL, since it originates from a non-extension process.
     EXPECT_NE(nested_urls[i], new_popup->GetLastCommittedURL());
     EXPECT_EQ("about:blank", new_popup->GetLastCommittedURL().spec());
-    EXPECT_NE("foo", GetTextContent(new_popup->GetMainFrame()));
+    EXPECT_NE("foo", GetTextContent(new_popup->GetPrimaryMainFrame()));
 
     EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
     EXPECT_EQ(1u, pm->GetAllFrames().size());
@@ -1381,7 +1386,7 @@
 
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // For this extension, only "*.html" resources are listed as web accessible;
   // "manifest.json" doesn't match that pattern, so it shouldn't be possible for
@@ -1428,7 +1433,7 @@
   ProcessManager* pm = ProcessManager::Get(profile());
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // Navigate the first iframe to a webaccessible resource of extension 2. This
   // should work.
@@ -1530,7 +1535,7 @@
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
 
   // Open a new web popup from the extension tab.  The popup should go into a
   // new process.
@@ -1538,7 +1543,8 @@
   content::WebContents* popup = OpenPopup(main_frame, popup_url);
   EXPECT_NE(popup, tab);
   ASSERT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_NE(popup->GetMainFrame()->GetProcess(), main_frame->GetProcess());
+  EXPECT_NE(popup->GetPrimaryMainFrame()->GetProcess(),
+            main_frame->GetProcess());
 
   // Ensure the popup's window.opener is defined.
   bool is_opener_defined = false;
@@ -1548,7 +1554,7 @@
   EXPECT_TRUE(is_opener_defined);
 
   // Verify that postMessage to window.opener works.
-  VerifyPostMessageToOpener(popup->GetMainFrame(), main_frame);
+  VerifyPostMessageToOpener(popup->GetPrimaryMainFrame(), main_frame);
 }
 
 // Verify that a web popup created via window.open from an extension subframe
@@ -1577,7 +1583,7 @@
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
   EXPECT_EQ(1u, pm->GetAllFrames().size());
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0);
 
   // Open a new web popup from extension frame.  The popup should go into main
@@ -1586,8 +1592,10 @@
   content::WebContents* popup = OpenPopup(extension_frame, popup_url);
   EXPECT_NE(popup, tab);
   ASSERT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_NE(popup->GetMainFrame()->GetProcess(), extension_frame->GetProcess());
-  EXPECT_EQ(popup->GetMainFrame()->GetProcess(), main_frame->GetProcess());
+  EXPECT_NE(popup->GetPrimaryMainFrame()->GetProcess(),
+            extension_frame->GetProcess());
+  EXPECT_EQ(popup->GetPrimaryMainFrame()->GetProcess(),
+            main_frame->GetProcess());
 
   // Ensure the popup's window.opener is defined.
   bool is_opener_defined = false;
@@ -1597,7 +1605,7 @@
   EXPECT_TRUE(is_opener_defined);
 
   // Verify that postMessage to window.opener works.
-  VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame);
+  VerifyPostMessageToOpener(popup->GetPrimaryMainFrame(), extension_frame);
 }
 
 // Test that when a web site has an extension iframe, navigating that iframe to
@@ -1631,7 +1639,7 @@
   EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
   EXPECT_EQ(1u, pm->GetAllFrames().size());
 
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   {
     content::RenderFrameHost* subframe = ChildFrameAt(main_frame, 0);
     EXPECT_NE(subframe->GetProcess(), main_frame->GetProcess());
@@ -1688,7 +1696,7 @@
   ExtensionHost* background_host =
       pm->GetBackgroundHostForExtension(extension->id());
   content::RenderFrameHost* background_rfh =
-      background_host->host_contents()->GetMainFrame();
+      background_host->host_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* extension_subframe =
       ChildFrameAt(background_rfh, 0);
   content::RenderFrameDeletedObserver deleted_observer(extension_subframe);
@@ -1705,7 +1713,7 @@
   EXPECT_EQ(foo_url, subframe->GetLastCommittedURL());
 
   // Verify that the subframe did *not* reuse the existing foo.com process.
-  EXPECT_NE(tab->GetMainFrame()->GetProcess(), subframe->GetProcess());
+  EXPECT_NE(tab->GetPrimaryMainFrame()->GetProcess(), subframe->GetProcess());
 }
 
 // Test to verify that loading a resource other than an icon file is
@@ -1765,7 +1773,7 @@
   std::u16string hosted_app_title = u"hosted_app";
   EXPECT_EQ(hosted_app_title,
             js_dialog_manager->GetTitle(
-                tab, tab->GetMainFrame()->GetLastCommittedOrigin()));
+                tab, tab->GetPrimaryMainFrame()->GetLastCommittedOrigin()));
 
   GURL web_url = embedded_test_server()->GetURL("/title1.html");
   ASSERT_TRUE(content::ExecuteScript(
@@ -1776,9 +1784,10 @@
   EXPECT_TRUE(content::WaitForLoadStop(new_tab));
   EXPECT_EQ(web_url, new_tab->GetLastCommittedURL());
   EXPECT_EQ(nullptr, pm->GetExtensionForWebContents(new_tab));
-  EXPECT_NE(hosted_app_title,
-            js_dialog_manager->GetTitle(
-                new_tab, new_tab->GetMainFrame()->GetLastCommittedOrigin()));
+  EXPECT_NE(
+      hosted_app_title,
+      js_dialog_manager->GetTitle(
+          new_tab, new_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin()));
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/protocol_handler_apitest.cc b/chrome/browser/extensions/protocol_handler_apitest.cc
index 5e574d2..025f1dce 100644
--- a/chrome/browser/extensions/protocol_handler_apitest.cc
+++ b/chrome/browser/extensions/protocol_handler_apitest.cc
@@ -152,8 +152,10 @@
 
   content::WebContentsDelegate* web_contents_delegate =
       browser()->tab_strip_model()->GetActiveWebContents()->GetDelegate();
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   std::vector<content::RenderFrameHost*> subframes =
       CollectAllRenderFrameHosts(main_frame);
   ASSERT_EQ(3u, subframes.size());
diff --git a/chrome/browser/extensions/sandboxed_pages_apitest.cc b/chrome/browser/extensions/sandboxed_pages_apitest.cc
index 5a33118..3dea12a 100644
--- a/chrome/browser/extensions/sandboxed_pages_apitest.cc
+++ b/chrome/browser/extensions/sandboxed_pages_apitest.cc
@@ -201,9 +201,9 @@
     EXPECT_EQ(result, fetch_url);
     histograms.ExpectBucketCount(kHistogramName, is_web_accessible_resource,
                                  count);
-    EXPECT_EQ(
-        expected_frame_origin,
-        web_contents->GetMainFrame()->GetLastCommittedOrigin().Serialize());
+    EXPECT_EQ(expected_frame_origin, web_contents->GetPrimaryMainFrame()
+                                         ->GetLastCommittedOrigin()
+                                         .Serialize());
   };
 
   // Extension page fetching an extension file.
diff --git a/chrome/browser/extensions/script_executor_browsertest.cc b/chrome/browser/extensions/script_executor_browsertest.cc
index 9d2d008..12a395a 100644
--- a/chrome/browser/extensions/script_executor_browsertest.cc
+++ b/chrome/browser/extensions/script_executor_browsertest.cc
@@ -117,7 +117,7 @@
     EXPECT_TRUE(nav_observer.last_navigation_succeeded());
   }
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
 
   constexpr char kSetFlagScript[] = "window.mainWorldFlag = 'executionFlag';";
   // NOTE: We use ExecuteScript() (and not EvalJs or ExecJs) because we
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index 1c4bd0a0..4a32075 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -1808,7 +1808,8 @@
   ExtensionTestMessageListener ready_listener("SERVICE_WORKER_READY");
   ready_listener.set_failure_message("SERVICE_WORKER_FAILURE");
   const char* kScript = "window.runServiceWorker()";
-  EXPECT_TRUE(content::ExecuteScript(web_contents->GetMainFrame(), kScript));
+  EXPECT_TRUE(
+      content::ExecuteScript(web_contents->GetPrimaryMainFrame(), kScript));
   EXPECT_TRUE(ready_listener.WaitUntilSatisfied());
 
   PushMessagingAppIdentifier app_identifier =
@@ -2831,7 +2832,7 @@
   // inherits the extension CSP.
   result = "";
   content::RenderFrameHost* iframe =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(iframe);
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(iframe, kScript, &result));
   EXPECT_EQ("PASS", result);
diff --git a/chrome/browser/extensions/subscribe_page_action_browsertest.cc b/chrome/browser/extensions/subscribe_page_action_browsertest.cc
index d6310aa2..25e0e15 100644
--- a/chrome/browser/extensions/subscribe_page_action_browsertest.cc
+++ b/chrome/browser/extensions/subscribe_page_action_browsertest.cc
@@ -165,8 +165,8 @@
   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
       tab->GetPrimaryPage(),
       base::BindRepeating(&content::FrameMatchesName, "preview"));
-  ASSERT_TRUE(ValidatePageElement(
-      tab->GetMainFrame(), kScriptFeedTitle, expected_feed_title));
+  ASSERT_TRUE(ValidatePageElement(tab->GetPrimaryMainFrame(), kScriptFeedTitle,
+                                  expected_feed_title));
   ASSERT_TRUE(ValidatePageElement(frame, kScriptAnchor, expected_item_title));
   ASSERT_TRUE(ValidatePageElement(frame, kScriptDesc, expected_item_desc));
   ASSERT_TRUE(ValidatePageElement(frame, kScriptError, expected_error));
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index bcced32d..397f8b4 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -164,7 +164,7 @@
   LoadTestExtension();
 
   content::MockNavigationHandle handle(GURL(kMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       CreateListenerNavigationThrottle(&handle);
   EXPECT_EQ(NavigationThrottle::DEFER, throttle->WillStartRequest());
@@ -181,7 +181,7 @@
   LoadTestExtension();
 
   content::MockNavigationHandle handle(GURL(kMatchingPrefsUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
 
   std::unique_ptr<NavigationThrottle> throttle =
       CreateListenerNavigationThrottle(&handle);
@@ -195,7 +195,7 @@
   LoadTestExtension();
 
   content::MockNavigationHandle handle(GURL(kMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       CreateListenerNavigationThrottle(&handle);
   EXPECT_EQ(NavigationThrottle::DEFER, throttle->WillStartRequest());
@@ -213,7 +213,7 @@
 
 TEST_F(UserScriptListenerTest, NoDelayNoExtension) {
   content::MockNavigationHandle handle(GURL(kMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       listener_.CreateNavigationThrottle(&handle);
   EXPECT_EQ(nullptr, throttle);
@@ -224,7 +224,7 @@
   LoadTestExtension();
 
   content::MockNavigationHandle handle(GURL(kNotMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       listener_.CreateNavigationThrottle(&handle);
   EXPECT_EQ(nullptr, throttle);
@@ -248,7 +248,7 @@
   registry->TriggerOnLoaded(extension.get());
 
   content::MockNavigationHandle handle(GURL(kMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       CreateListenerNavigationThrottle(&handle);
   EXPECT_EQ(NavigationThrottle::DEFER, throttle->WillStartRequest());
@@ -269,7 +269,7 @@
 TEST_F(UserScriptListenerTest, ResumeBeforeStart) {
   LoadTestExtension();
   content::MockNavigationHandle handle(GURL(kMatchingUrl),
-                                       web_contents_->GetMainFrame());
+                                       web_contents_->GetPrimaryMainFrame());
   std::unique_ptr<NavigationThrottle> throttle =
       listener_.CreateNavigationThrottle(&handle);
   ASSERT_TRUE(throttle);
diff --git a/chrome/browser/extensions/view_extension_source_browsertest.cc b/chrome/browser/extensions/view_extension_source_browsertest.cc
index 21025dd..28712c3 100644
--- a/chrome/browser/extensions/view_extension_source_browsertest.cc
+++ b/chrome/browser/extensions/view_extension_source_browsertest.cc
@@ -35,7 +35,7 @@
   content::WebContents* bookmarks_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
   GURL bookmarks_extension_url =
-      bookmarks_tab->GetMainFrame()->GetLastCommittedURL();
+      bookmarks_tab->GetPrimaryMainFrame()->GetLastCommittedURL();
   EXPECT_TRUE(bookmarks_extension_url.SchemeIs(extensions::kExtensionScheme));
 
   // Open a new view-source tab for that URL.
@@ -46,7 +46,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(view_source_url, view_source_tab->GetVisibleURL());
   EXPECT_EQ(bookmarks_extension_url,
-            view_source_tab->GetMainFrame()->GetLastCommittedURL());
+            view_source_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_FALSE(chrome::CanViewSource(browser()));
 
   // Close the view-source tab.
@@ -67,7 +67,7 @@
   // view-source:chrome-extension://.../.
   EXPECT_EQ(view_source_url, view_source_tab->GetVisibleURL());
   EXPECT_EQ(bookmarks_extension_url,
-            view_source_tab->GetMainFrame()->GetLastCommittedURL());
+            view_source_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_FALSE(chrome::CanViewSource(browser()));
 
   // Verify that the view-source content is not empty, and that the
diff --git a/chrome/browser/extensions/web_contents_browsertest.cc b/chrome/browser/extensions/web_contents_browsertest.cc
index 3bbfa63..c361922 100644
--- a/chrome/browser/extensions/web_contents_browsertest.cc
+++ b/chrome/browser/extensions/web_contents_browsertest.cc
@@ -207,7 +207,8 @@
   // Test ExtensionNavigationUIData for the main frame.
   {
     const auto* extension_navigation_ui_data =
-        observer.GetExtensionNavigationUIData(web_contents->GetMainFrame());
+        observer.GetExtensionNavigationUIData(
+            web_contents->GetPrimaryMainFrame());
     ASSERT_TRUE(extension_navigation_ui_data);
     EXPECT_FALSE(extension_navigation_ui_data->is_web_view());
 
@@ -224,7 +225,7 @@
   {
     const auto* extension_navigation_ui_data =
         observer.GetExtensionNavigationUIData(
-            content::ChildFrameAt(web_contents->GetMainFrame(), 0));
+            content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0));
     ASSERT_TRUE(extension_navigation_ui_data);
     EXPECT_FALSE(extension_navigation_ui_data->is_web_view());
 
diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
index 2c792f3..b39abab 100644
--- a/chrome/browser/extensions/webstore_installer.cc
+++ b/chrome/browser/extensions/webstore_installer.cc
@@ -596,11 +596,13 @@
     ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
     return;
   }
-  if (!web_contents_->GetMainFrame()->GetRenderViewHost()) {
+  if (!web_contents_->GetPrimaryMainFrame()->GetRenderViewHost()) {
     ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
     return;
   }
-  if (!web_contents_->GetMainFrame()->GetRenderViewHost()->GetProcess()) {
+  if (!web_contents_->GetPrimaryMainFrame()
+           ->GetRenderViewHost()
+           ->GetProcess()) {
     ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
     return;
   }
@@ -618,10 +620,13 @@
   // The download url for the given extension is contained in |download_url_|.
   // We will navigate the current tab to this url to start the download. The
   // download system will then pass the crx to the CrxInstaller.
-  int render_process_host_id =
-      web_contents_->GetMainFrame()->GetRenderViewHost()->GetProcess()->GetID();
+  int render_process_host_id = web_contents_->GetPrimaryMainFrame()
+                                   ->GetRenderViewHost()
+                                   ->GetProcess()
+                                   ->GetID();
 
-  content::RenderFrameHost* render_frame_host = web_contents_->GetMainFrame();
+  content::RenderFrameHost* render_frame_host =
+      web_contents_->GetPrimaryMainFrame();
   net::NetworkTrafficAnnotationTag traffic_annotation =
       net::DefineNetworkTrafficAnnotation("webstore_installer", R"(
         semantics {
diff --git a/chrome/browser/extensions/webstore_installer_test.cc b/chrome/browser/extensions/webstore_installer_test.cc
index 906a7b8..fd65a4d2 100644
--- a/chrome/browser/extensions/webstore_installer_test.cc
+++ b/chrome/browser/extensions/webstore_installer_test.cc
@@ -138,7 +138,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(script),
                                                  base::NullCallback());
 }
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc
index 01fe854..99e9b127 100644
--- a/chrome/browser/extensions/window_open_apitest.cc
+++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -268,7 +268,7 @@
       broken_extension_url, new_page_in_same_process, expect_success, &newtab));
 
   EXPECT_EQ(broken_extension_url,
-            newtab->GetMainFrame()->GetLastCommittedURL());
+            newtab->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(content::PAGE_TYPE_ERROR,
             newtab->GetController().GetLastCommittedEntry()->GetPageType());
 }
@@ -319,9 +319,11 @@
 
   EXPECT_EQ(content::PAGE_TYPE_ERROR,
             newtab->GetController().GetLastCommittedEntry()->GetPageType());
-  EXPECT_EQ(extension_url, newtab->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_FALSE(newtab->GetMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
-      extensions::kExtensionScheme));
+  EXPECT_EQ(extension_url,
+            newtab->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_FALSE(
+      newtab->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
+          extensions::kExtensionScheme));
 }
 
 // Test that navigating to an extension URL is allowed on chrome://.
@@ -342,13 +344,13 @@
   GURL history_url(chrome::kChromeUIHistoryURL);
   ASSERT_TRUE(history_url.SchemeIs(content::kChromeUIScheme));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), history_url));
-  EXPECT_EQ(history_url, tab->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(history_url, tab->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   content::TestNavigationObserver observer(tab);
   ASSERT_TRUE(content::ExecuteScript(
       tab, "location.href = '" + extension_url.spec() + "';"));
   observer.Wait();
-  EXPECT_EQ(extension_url, tab->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(extension_url, tab->GetPrimaryMainFrame()->GetLastCommittedURL());
   std::string result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       tab, "domAutomationController.send(document.body.innerText)", &result));
diff --git a/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc b/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc
index 4d2a342a..49bc4ef 100644
--- a/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc
@@ -224,25 +224,26 @@
 // - allow-top-navigation-by-user-activation + UserGesture
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest, Sandbox) {
   EXPECT_TRUE(
-      AllowedBySandbox(CreateIFrame(web_content()->GetMainFrame(), "")));
+      AllowedBySandbox(CreateIFrame(web_content()->GetPrimaryMainFrame(), "")));
 }
 
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest, SandboxAll) {
-  EXPECT_FALSE(AllowedBySandbox(CreateIFrame(
-      web_content()->GetMainFrame(), "iframe.sandbox = 'allow-scripts';")));
+  EXPECT_FALSE(
+      AllowedBySandbox(CreateIFrame(web_content()->GetPrimaryMainFrame(),
+                                    "iframe.sandbox = 'allow-scripts';")));
 }
 
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest,
                        SandboxAllowPopups) {
   EXPECT_TRUE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts allow-popups';")));
 }
 
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest,
                        SandboxAllowTopNavigationToCustomProtocols) {
   EXPECT_TRUE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts "
                    "allow-top-navigation-to-custom-protocols';")));
 }
@@ -250,14 +251,14 @@
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest,
                        SandboxAllowTopNavigation) {
   EXPECT_TRUE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts allow-top-navigation';")));
 }
 
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest,
                        SandboxAllowTopNavigationByUserActivation) {
   EXPECT_FALSE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts "
                    "allow-top-navigation-by-user-activation';"),
       /*user-gesture=*/false));
@@ -266,7 +267,7 @@
 IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerSandboxBrowserTest,
                        SandboxAllowTopNavigationByUserActivationWithGesture) {
   EXPECT_TRUE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts "
                    "allow-top-navigation-by-user-activation';"),
       /*user-gesture=*/true));
@@ -350,7 +351,7 @@
 
   content::RenderFrameHost* CreateFencedFrame() {
     return fenced_frame_test_helper().CreateFencedFrame(
-        web_content()->GetMainFrame(),
+        web_content()->GetPrimaryMainFrame(),
         embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   }
 
@@ -417,7 +418,7 @@
     ExternalProtocolHandlerSandboxFencedFrameBrowserTest,
     SandboxAllowTopNavigationByUserActivationWithGestureInFencedFrame) {
   EXPECT_TRUE(AllowedBySandbox(
-      CreateIFrame(web_content()->GetMainFrame(),
+      CreateIFrame(web_content()->GetPrimaryMainFrame(),
                    "iframe.sandbox = 'allow-scripts "
                    "allow-top-navigation-by-user-activation';"),
       /*user-gesture=*/true));
diff --git a/chrome/browser/favicon/content_favicon_driver_browsertest.cc b/chrome/browser/favicon/content_favicon_driver_browsertest.cc
index ec526a1..64aca7b 100644
--- a/chrome/browser/favicon/content_favicon_driver_browsertest.cc
+++ b/chrome/browser/favicon/content_favicon_driver_browsertest.cc
@@ -319,8 +319,8 @@
       embedded_test_server()->GetURL("/favicon/page_with_favicon.html");
   GURL icon_url = embedded_test_server()->GetURL("/favicon/icon.png");
   GURL initial_url = embedded_test_server()->GetURL("/empty.html");
-  EXPECT_CALL(observer,
-              DidUpdateFaviconURL(web_contents()->GetMainFrame(), testing::_));
+  EXPECT_CALL(observer, DidUpdateFaviconURL(
+                            web_contents()->GetPrimaryMainFrame(), testing::_));
   prerender_helper().NavigatePrimaryPage(initial_url);
 
   {
diff --git a/chrome/browser/feed/rss_links_fetcher.cc b/chrome/browser/feed/rss_links_fetcher.cc
index a6ef779..33f79be 100644
--- a/chrome/browser/feed/rss_links_fetcher.cc
+++ b/chrome/browser/feed/rss_links_fetcher.cc
@@ -15,10 +15,10 @@
 
 mojo::Remote<feed::mojom::RssLinkReader> GetRssLinkReaderRemote(
     content::WebContents* web_contents) {
-  DCHECK(web_contents->GetMainFrame()->IsRenderFrameLive());
+  DCHECK(web_contents->GetPrimaryMainFrame()->IsRenderFrameLive());
   mojo::Remote<feed::mojom::RssLinkReader> result;
   // GetRemoteInterfaces() cannot be null if the render frame is created.
-  web_contents->GetMainFrame()->GetRemoteInterfaces()->GetInterface(
+  web_contents->GetPrimaryMainFrame()->GetRemoteInterfaces()->GetInterface(
       result.BindNewPipeAndPassReceiver());
   return result;
 }
diff --git a/chrome/browser/feed/web_feed_page_information_fetcher.cc b/chrome/browser/feed/web_feed_page_information_fetcher.cc
index 1209f11..88a0ada 100644
--- a/chrome/browser/feed/web_feed_page_information_fetcher.cc
+++ b/chrome/browser/feed/web_feed_page_information_fetcher.cc
@@ -19,8 +19,9 @@
 void FetchPageCanonicalUrl(
     const PageInformation& page_info,
     base::OnceCallback<void(const absl::optional<::GURL>&)> callback) {
-  DCHECK(page_info.web_contents->GetMainFrame()->IsRenderFrameLive());
-  page_info.web_contents->GetMainFrame()->GetCanonicalUrl(std::move(callback));
+  DCHECK(page_info.web_contents->GetPrimaryMainFrame()->IsRenderFrameLive());
+  page_info.web_contents->GetPrimaryMainFrame()->GetCanonicalUrl(
+      std::move(callback));
 }
 
 }  // namespace
@@ -36,7 +37,7 @@
 
   // Make sure the renderer still exists, i.e., not crashed, since this may
   // be triggered asynchronously.
-  if (!page_info.web_contents->GetMainFrame()->IsRenderFrameLive()) {
+  if (!page_info.web_contents->GetPrimaryMainFrame()->IsRenderFrameLive()) {
     std::move(callback).Run(WebFeedPageInformation());
     return;
   }
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
index 03c0336d..b251931a 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -1468,7 +1468,7 @@
       content::WebContents* web_contents = tabs->GetWebContentsAt(i);
       url::Origin tab_origin = url::Origin::Create(
           permissions::PermissionUtil::GetLastCommittedOriginAsURL(
-              web_contents->GetMainFrame()));
+              web_contents->GetPrimaryMainFrame()));
       // Found a tab for this origin, so early exit and don't revoke grants.
       if (tab_origin == origin)
         return;
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
index bca3a39..e177be3e 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
@@ -227,7 +227,7 @@
   // Activate the prerendered page.
   prerender_helper().NavigatePrimaryPage(prerender_url);
   content::UpdateUserActivationStateInterceptor user_activation_interceptor(
-      GetWebContents()->GetMainFrame());
+      GetWebContents()->GetPrimaryMainFrame());
   user_activation_interceptor.UpdateUserActivationState(
       blink::mojom::UserActivationUpdateType::kNotifyActivation,
       blink::mojom::UserActivationNotificationType::kTest);
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
index dfd38b2..a0e46626 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -152,12 +152,12 @@
   WebContents* web_contents() { return web_contents_.get(); }
 
   int process_id() {
-    return web_contents()->GetMainFrame()->GetProcess()->GetID();
+    return web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
   }
 
   content::GlobalRenderFrameHostId frame_id() {
     return content::GlobalRenderFrameHostId(
-        process_id(), web_contents()->GetMainFrame()->GetRoutingID());
+        process_id(), web_contents()->GetPrimaryMainFrame()->GetRoutingID());
   }
 
   base::Time Now() const { return task_environment_.GetMockClock()->Now(); }
@@ -1577,7 +1577,7 @@
        RequestPermission_Dismissed) {
   FileSystemAccessPermissionRequestManager::FromWebContents(web_contents())
       ->set_auto_response_for_test(PermissionAction::DISMISSED);
-  content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
+  content::RenderFrameHostTester::For(web_contents_->GetPrimaryMainFrame())
       ->SimulateUserActivation();
 
   auto grant = permission_context()->GetWritePermissionGrant(
@@ -1600,7 +1600,7 @@
 TEST_F(ChromeFileSystemAccessPermissionContextTest, RequestPermission_Granted) {
   FileSystemAccessPermissionRequestManager::FromWebContents(web_contents())
       ->set_auto_response_for_test(PermissionAction::GRANTED);
-  content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
+  content::RenderFrameHostTester::For(web_contents_->GetPrimaryMainFrame())
       ->SimulateUserActivation();
 
   auto grant = permission_context()->GetWritePermissionGrant(
@@ -1622,7 +1622,7 @@
 TEST_F(ChromeFileSystemAccessPermissionContextTest, RequestPermission_Denied) {
   FileSystemAccessPermissionRequestManager::FromWebContents(web_contents())
       ->set_auto_response_for_test(PermissionAction::DENIED);
-  content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
+  content::RenderFrameHostTester::For(web_contents_->GetPrimaryMainFrame())
       ->SimulateUserActivation();
 
   auto grant = permission_context()->GetWritePermissionGrant(
diff --git a/chrome/browser/file_system_access/file_system_access_tab_helper.cc b/chrome/browser/file_system_access/file_system_access_tab_helper.cc
index 9a8761f6..8993dc4d 100644
--- a/chrome/browser/file_system_access/file_system_access_tab_helper.cc
+++ b/chrome/browser/file_system_access/file_system_access_tab_helper.cc
@@ -32,7 +32,8 @@
 }
 
 void FileSystemAccessTabHelper::WebContentsDestroyed() {
-  auto src_origin = web_contents()->GetMainFrame()->GetLastCommittedOrigin();
+  auto src_origin =
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
 
   // Navigated away from |src_origin|, tell permission context to check if
   // permissions need to be revoked.
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc b/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc
index dfd6e97e..9a64a43a 100644
--- a/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc
+++ b/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc
@@ -293,7 +293,7 @@
   ASSERT_TRUE(NavigateToURL(
       web_contents(), https_server()->GetURL(kHostA, "/echoheader?Cookie")));
   EXPECT_THAT(
-      ExtractFrameContent(web_contents()->GetMainFrame()),
+      ExtractFrameContent(web_contents()->GetPrimaryMainFrame()),
       net::CookieStringIs(UnorderedPointwise(net::NameIs(), kAllCookies)));
 }
 
@@ -402,7 +402,7 @@
   ASSERT_TRUE(NavigateToURL(
       web_contents(), https_server()->GetURL(kHostD, "/echoheader?Cookie")));
   EXPECT_THAT(
-      ExtractFrameContent(web_contents()->GetMainFrame()),
+      ExtractFrameContent(web_contents()->GetPrimaryMainFrame()),
       net::CookieStringIs(UnorderedPointwise(net::NameIs(), kAllCookies)));
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 0d565e5c..166756c 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -6324,6 +6324,11 @@
     "expiry_milestone": 105
   },
   {
+    "name": "webpage-text-zoom-ipad",
+    "owners": [ "rkgibson@google.com", "bling-flags@google.com" ],
+    "expiry_milestone": 108
+  },
+  {
     "name": "webui-tab-strip",
     "owners": [
       "yuhengh",
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc
index a6ccca7..097440b 100644
--- a/chrome/browser/geolocation/geolocation_browsertest.cc
+++ b/chrome/browser/geolocation/geolocation_browsertest.cc
@@ -101,7 +101,7 @@
   std::string script(base::StringPrintf(
       "window.domAutomationController.send(addIFrame(%d, \"%s\"));",
       iframe_id, url.spec().c_str()));
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       base::UTF8ToUTF16(script), base::NullCallback());
 
   quit_closure_ = run_loop.QuitWhenIdleClosure();
@@ -112,7 +112,7 @@
   // Now that we loaded the iframe, let's fetch its src.
   script = base::StringPrintf(
       "window.domAutomationController.send(getIFrameSrc(%d))", iframe_id);
-  iframe_url_ = GURL(RunScript(web_contents->GetMainFrame(), script));
+  iframe_url_ = GURL(RunScript(web_contents->GetPrimaryMainFrame(), script));
 }
 
 IFrameLoader::~IFrameLoader() {
@@ -303,7 +303,7 @@
   render_frame_host_ = nullptr;
 
   if (frame_name.empty()) {
-    render_frame_host_ = web_contents()->GetMainFrame();
+    render_frame_host_ = web_contents()->GetPrimaryMainFrame();
   } else {
     render_frame_host_ = content::FrameMatchingPredicate(
         web_contents()->GetPrimaryPage(),
@@ -532,7 +532,8 @@
   content::WebContents* original_tab = web_contents();
   ExpectValueFromScript(GetErrorCodePermissionDenied(),
                         "requestGeolocationFromInvalidUrl()");
-  ExpectValueFromScriptForFrame("1", "isAlive()", original_tab->GetMainFrame());
+  ExpectValueFromScriptForFrame("1", "isAlive()",
+                                original_tab->GetPrimaryMainFrame());
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoPromptBeforeStart) {
diff --git a/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc
index b34ad2f..ca7dabc 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc
@@ -116,7 +116,7 @@
   run_loop.Run();
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents()->GetMainFrame());
+          web_contents()->GetPrimaryMainFrame());
   EXPECT_TRUE(
       content_settings->IsContentAllowed(ContentSettingsType::GEOLOCATION));
 }
diff --git a/chrome/browser/geolocation/geolocation_permission_context_extensions.cc b/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
index bcde340..0840727 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_extensions.cc
@@ -83,7 +83,7 @@
             requesting_frame_origin);
     if (IsExtensionWithPermissionOrSuggestInConsole(
             extensions::mojom::APIPermissionID::kGeolocation, extension,
-            web_contents->GetMainFrame())) {
+            web_contents->GetPrimaryMainFrame())) {
       // Make sure the extension is in the calling process.
       if (extensions::ProcessMap::Get(profile_)->Contains(
               extension->id(), request_id.render_process_id())) {
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
index 79d9339..f67c93b01 100644
--- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
+++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
@@ -161,7 +161,7 @@
 class UserActivationUpdateWaiter {
  public:
   explicit UserActivationUpdateWaiter(content::WebContents* web_contents)
-      : user_activation_interceptor_(web_contents->GetMainFrame()) {}
+      : user_activation_interceptor_(web_contents->GetPrimaryMainFrame()) {}
   ~UserActivationUpdateWaiter() = default;
 
   void Wait() {
@@ -332,7 +332,7 @@
   int32_t element_instance_id = guest_view->element_instance_id();
   auto* embedder_web_contents = GetEmbedderWebContents();
   auto* child_frame =
-      content::ChildFrameAt(embedder_web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(embedder_web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameDeletedObserver render_frame_observer(child_frame);
   ASSERT_TRUE(
       content::ExecJs(embedder_web_contents,
@@ -342,7 +342,7 @@
   // removed from the global map.
   mojo::AssociatedRemote<extensions::mojom::MimeHandlerViewContainerManager>
       container_manager;
-  embedder_web_contents->GetMainFrame()
+  embedder_web_contents->GetPrimaryMainFrame()
       ->GetRemoteAssociatedInterfaces()
       ->GetInterface(&container_manager);
   container_manager->DestroyFrameContainer(element_instance_id);
@@ -371,7 +371,7 @@
       browser(),
       embedded_test_server()->GetURL("a.com", "/test_object_with_frame.html")));
   auto* main_frame =
-      browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame();
+      browser()->tab_strip_model()->GetWebContentsAt(0)->GetPrimaryMainFrame();
   auto url_with_beforeunload =
       embedded_test_server()->GetURL("b.com", "/test_page.html?beforeunload");
   bool result = false;
@@ -473,7 +473,7 @@
 
   // Wait for a round trip to the outer renderer to ensure any beforeunload
   // toggle IPC has had time to reach the browser.
-  ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "");
+  ExecuteScriptAndGetValue(web_contents->GetPrimaryMainFrame(), "");
 
   // Try to navigate away from the page. If the beforeunload listener is
   // triggered and a dialog is shown, this navigation will never complete,
@@ -489,7 +489,7 @@
 
   // Wait for a round trip to the outer renderer to ensure the beforeunload
   // toggle IPC has had time to reach the browser.
-  ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "");
+  ExecuteScriptAndGetValue(web_contents->GetPrimaryMainFrame(), "");
 
   web_contents->GetController().LoadURL(GURL(url::kAboutBlankURL), {},
                                         ui::PAGE_TRANSITION_TYPED, "");
@@ -534,7 +534,7 @@
 
   // Wait for a round trip to the outer renderer to ensure any beforeunload
   // toggle IPC has had time to reach the browser.
-  ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "");
+  ExecuteScriptAndGetValue(web_contents->GetPrimaryMainFrame(), "");
 
   // Try to navigate away, this should invoke a beforeunload dialog.
   web_contents->GetController().LoadURL(GURL(url::kAboutBlankURL), {},
@@ -600,7 +600,8 @@
   ASSERT_EQ(1U, guest_view_manager->num_guests_created());
 
   // Remove the non-sandboxed frame.
-  content::RenderFrameHost* main_rfh = GetEmbedderWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_rfh =
+      GetEmbedderWebContents()->GetPrimaryMainFrame();
   ASSERT_TRUE(content::ExecJs(main_rfh, "remove_frame('notsandboxed');"));
   // The page is expected to embed only '1' GuestView. If there is GuestViews
   // embedded inside other frames we should be timing out here.
@@ -649,7 +650,7 @@
     run_loop.Run();
   }
   EXPECT_TRUE(WaitForLoadStop(guest_contents));
-  content::RenderFrameHost* guest_rfh = guest_contents->GetMainFrame();
+  content::RenderFrameHost* guest_rfh = guest_contents->GetPrimaryMainFrame();
   EXPECT_EQ(false, content::EvalJs(guest_rfh, R"code(
     var promise = new Promise((resolve, reject) => {
       document.addEventListener('pointerlockchange', () => resolve(true));
@@ -718,7 +719,7 @@
 
   // Verify that print dialog comes up.
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   // Use setTimeout() to prevent ExecuteScript() from blocking on the print
   // dialog.
   ASSERT_TRUE(content::ExecuteScript(
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
index 44b8c79..47230ae 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
@@ -193,7 +193,7 @@
       ->GetPermissionController()
       ->RequestPermissionFromCurrentDocument(
           blink::PermissionType::GEOLOCATION,
-          web_view_guest()->embedder_web_contents()->GetMainFrame(),
+          web_view_guest()->embedder_web_contents()->GetPrimaryMainFrame(),
           user_gesture, std::move(callback));
 }
 
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc b/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc
index bc90980..024a78b 100644
--- a/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc
+++ b/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc
@@ -59,7 +59,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   content::WebContentsConsoleObserver console_observer(web_contents);
 
@@ -90,7 +90,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   content::TestNavigationObserver error_observer(web_contents);
   controller.LoadPostCommitErrorPage(
@@ -105,7 +105,7 @@
   // instance.
   if (content::SiteIsolationPolicy::IsErrorPageIsolationEnabled(
           /* in_main_frame = */ false)) {
-    child = ChildFrameAt(web_contents->GetMainFrame(), 0);
+    child = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   }
 
   EXPECT_TRUE(IsContentInDocument(
diff --git a/chrome/browser/history/history_browsertest.cc b/chrome/browser/history/history_browsertest.cc
index 4fbe1f4..246ce55 100644
--- a/chrome/browser/history/history_browsertest.cc
+++ b/chrome/browser/history/history_browsertest.cc
@@ -1004,7 +1004,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
 
   // Navigate the fenced frame.
   last_load_completion_before_navigation =
diff --git a/chrome/browser/icon_transcoder/svg_icon_transcoder.cc b/chrome/browser/icon_transcoder/svg_icon_transcoder.cc
index 7b2d8bb8..5bbd093 100644
--- a/chrome/browser/icon_transcoder/svg_icon_transcoder.cc
+++ b/chrome/browser/icon_transcoder/svg_icon_transcoder.cc
@@ -121,7 +121,7 @@
         content::WebContents::CreateParams::kInitializeAndWarmupRendererProcess;
     web_contents_ = content::WebContents::Create(params);
     // When we observe RenderProcessExited, we will need to recreate.
-    web_contents_->GetMainFrame()->GetProcess()->AddObserver(this);
+    web_contents_->GetPrimaryMainFrame()->GetProcess()->AddObserver(this);
   }
 }
 
@@ -129,7 +129,7 @@
   if (!web_contents_ready_) {
     // Old web_contents_ may have been destroyed.
     MaybeCreateWebContents();
-    if (web_contents_->GetMainFrame()->IsRenderFrameLive()) {
+    if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
       web_contents_ready_ = true;
     }
     VLOG(1) << "web_contents "
@@ -151,8 +151,8 @@
 }
 
 void SvgIconTranscoder::RemoveObserver() {
-  if (web_contents_ && web_contents_->GetMainFrame()) {
-    web_contents_->GetMainFrame()->GetProcess()->RemoveObserver(this);
+  if (web_contents_ && web_contents_->GetPrimaryMainFrame()) {
+    web_contents_->GetPrimaryMainFrame()->GetProcess()->RemoveObserver(this);
   }
 }
 
diff --git a/chrome/browser/idle/idle_browsertest.cc b/chrome/browser/idle/idle_browsertest.cc
index 861752d..eef7916 100644
--- a/chrome/browser/idle/idle_browsertest.cc
+++ b/chrome/browser/idle/idle_browsertest.cc
@@ -87,7 +87,7 @@
     std::string script = "IdleDetector.requestPermission();";
 
     content::RenderFrameHost* child =
-        ChildFrameAt(web_contents()->GetMainFrame(), 0);
+        ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
 
     EXPECT_EQ(positive_test ? "granted" : "denied", EvalJs(child, script));
   }
diff --git a/chrome/browser/idle/idle_detection_permission_context_unittest.cc b/chrome/browser/idle/idle_detection_permission_context_unittest.cc
index 60cba843..b751c4b 100644
--- a/chrome/browser/idle/idle_detection_permission_context_unittest.cc
+++ b/chrome/browser/idle/idle_detection_permission_context_unittest.cc
@@ -79,8 +79,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -145,12 +145,12 @@
   web_contents()->WasShown();
 
   const permissions::PermissionRequestID id1(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId(1));
   const permissions::PermissionRequestID id2(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId(2));
 
   ASSERT_EQ(0, permission_context.permission_set_count());
diff --git a/chrome/browser/iframe_browsertest.cc b/chrome/browser/iframe_browsertest.cc
index 6b0928ea..11b7ae6 100644
--- a/chrome/browser/iframe_browsertest.cc
+++ b/chrome/browser/iframe_browsertest.cc
@@ -59,15 +59,16 @@
   NavigateIframeToURL(tab, "test", file_input_url);
 
   // Invoke the file chooser and remove the iframe from the main document.
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_EQ(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_EQ(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
   EXPECT_TRUE(
       ExecuteScript(frame, "document.getElementById('fileinput').click();"));
-  EXPECT_TRUE(ExecuteScript(tab->GetMainFrame(),
+  EXPECT_TRUE(ExecuteScript(tab->GetPrimaryMainFrame(),
                             "document.body.removeChild("
                             "document.querySelectorAll('iframe')[0])"));
-  ASSERT_EQ(nullptr, ChildFrameAt(tab->GetMainFrame(), 0));
+  ASSERT_EQ(nullptr, ChildFrameAt(tab->GetPrimaryMainFrame(), 0));
 
   // On ASan bots, this test should succeed without reporting use-after-free
   // condition.
diff --git a/chrome/browser/image_editor/screenshot_flow.cc b/chrome/browser/image_editor/screenshot_flow.cc
index 0fb6a5d..5f98ade 100644
--- a/chrome/browser/image_editor/screenshot_flow.cc
+++ b/chrome/browser/image_editor/screenshot_flow.cc
@@ -389,7 +389,7 @@
 #endif
 
   content::RenderWidgetHost* host =
-      web_contents_->GetMainFrame()->GetRenderWidgetHost();
+      web_contents_->GetPrimaryMainFrame()->GetRenderWidgetHost();
   if (host) {
     ui::Cursor cursor(cursor_type);
     host->SetCursor(cursor);
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc
index 51c900b2..b1017bf 100644
--- a/chrome/browser/installable/installable_manager_browsertest.cc
+++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -1963,7 +1963,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   static_cast<content::WebContentsObserver*>(manager)->DidUpdateWebManifestURL(
-      web_contents->GetMainFrame(), GURL());
+      web_contents->GetPrimaryMainFrame(), GURL());
   run_loop.Run();
 
   ASSERT_EQ(tester->errors().size(), 1u);
diff --git a/chrome/browser/interstitials/security_interstitial_idn_test.cc b/chrome/browser/interstitials/security_interstitial_idn_test.cc
index 7009e4c..14d297d 100644
--- a/chrome/browser/interstitials/security_interstitial_idn_test.cc
+++ b/chrome/browser/interstitials/security_interstitial_idn_test.cc
@@ -31,8 +31,8 @@
       CreateInterstitial(contents, request_url);
   content::TestNavigationObserver observer(contents);
   contents->GetController().LoadPostCommitErrorPage(
-      contents->GetMainFrame(), request_url, blocking_page->GetHTMLContents(),
-      net::ERR_BLOCKED_BY_CLIENT);
+      contents->GetPrimaryMainFrame(), request_url,
+      blocking_page->GetHTMLContents(), net::ERR_BLOCKED_BY_CLIENT);
   observer.Wait();
   delete blocking_page;
   if (ui_test_utils::FindInPage(contents, kHostnameUnicode, true /*forward*/,
diff --git a/chrome/browser/interstitials/security_interstitial_page_test_utils.cc b/chrome/browser/interstitials/security_interstitial_page_test_utils.cc
index 9f989863..46da56b 100644
--- a/chrome/browser/interstitials/security_interstitial_page_test_utils.cc
+++ b/chrome/browser/interstitials/security_interstitial_page_test_utils.cc
@@ -54,35 +54,36 @@
 
 bool IsShowingCaptivePortalInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(), "Connect to");
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(), "Connect to");
 }
 
 bool IsShowingSSLInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(),
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(),
                                       "Your connection is not private");
 }
 
 bool IsShowingMITMInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(),
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(),
                                       "An application is stopping");
 }
 
 bool IsShowingBadClockInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(), "Your clock is");
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(),
+                                      "Your clock is");
 }
 
 bool IsShowingBlockedInterceptionInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(),
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(),
                                       "Anything you type, any pages you view");
 }
 
 bool IsShowingHttpsFirstModeInterstitial(content::WebContents* tab) {
   return IsShowingInterstitial(tab) &&
-         IsInterstitialDisplayingText(tab->GetMainFrame(),
+         IsInterstitialDisplayingText(tab->GetPrimaryMainFrame(),
                                       "this site does not support HTTPS.");
 }
 
diff --git a/chrome/browser/interstitials/security_interstitial_page_test_utils.h b/chrome/browser/interstitials/security_interstitial_page_test_utils.h
index 7ee50c3..23507b3 100644
--- a/chrome/browser/interstitials/security_interstitial_page_test_utils.h
+++ b/chrome/browser/interstitials/security_interstitial_page_test_utils.h
@@ -17,8 +17,8 @@
 // Looks for text in the |textContent| of |interstitial_frame|'s body and
 // returns true if found. This can be used for either transient or committed
 // interstitials. For the former, pass
-// web_contents->GetInterstitialPage()->GetMainFrame() as the first argument,
-// and for the latter, just pass web_contents->GetMainFrame().
+// web_contents->GetInterstitialPage()->GetPrimaryMainFrame() as the first
+// argument, and for the latter, just pass web_contents->GetPrimaryMainFrame().
 bool IsInterstitialDisplayingText(content::RenderFrameHost* interstitial_frame,
                                   const std::string& text);
 
diff --git a/chrome/browser/lacros/web_page_info_lacros.cc b/chrome/browser/lacros/web_page_info_lacros.cc
index b0911c60..5f28ab7 100644
--- a/chrome/browser/lacros/web_page_info_lacros.cc
+++ b/chrome/browser/lacros/web_page_info_lacros.cc
@@ -29,7 +29,8 @@
   if (!contents)
     return nullptr;
 
-  ukm::SourceId source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   if (source_id == ukm::kInvalidSourceId)
     return nullptr;
 
diff --git a/chrome/browser/lifetime/browser_shutdown.cc b/chrome/browser/lifetime/browser_shutdown.cc
index 4627bb3..e5f9e550 100644
--- a/chrome/browser/lifetime/browser_shutdown.cc
+++ b/chrome/browser/lifetime/browser_shutdown.cc
@@ -320,40 +320,34 @@
   if (shutdown_ms == 0 || num_procs == 0)
     return;
 
-  const char* time2_metric_name = nullptr;
-  const char* per_proc_metric_name = nullptr;
-
+  const char* time_metric_name = nullptr;
   switch (type) {
     case ShutdownType::kNotValid:
+      time_metric_name = "Shutdown.NotValid.Time";
+      break;
+
     case ShutdownType::kSilentExit:
-      // The histograms below have expired, so do not record metrics for silent
-      // exits; see https://crbug.com/975118.
+      time_metric_name = "Shutdown.SilentExit.time";
       break;
 
     case ShutdownType::kWindowClose:
-      time2_metric_name = "Shutdown.window_close.time2";
-      per_proc_metric_name = "Shutdown.window_close.time_per_process";
+      time_metric_name = "Shutdown.WindowClose.Time";
       break;
 
     case ShutdownType::kBrowserExit:
-      time2_metric_name = "Shutdown.browser_exit.time2";
-      per_proc_metric_name = "Shutdown.browser_exit.time_per_process";
+      time_metric_name = "Shutdown.BrowserExit.Time";
       break;
 
     case ShutdownType::kEndSession:
-      time2_metric_name = "Shutdown.end_session.time2";
-      per_proc_metric_name = "Shutdown.end_session.time_per_process";
+      time_metric_name = "Shutdown.EndSession.Time";
       break;
   }
-  if (!time2_metric_name)
-    return;
+  DCHECK(time_metric_name);
 
-  base::UmaHistogramMediumTimes(time2_metric_name,
+  base::UmaHistogramMediumTimes(time_metric_name,
                                 base::Milliseconds(shutdown_ms));
-  base::UmaHistogramTimes(per_proc_metric_name,
-                          base::Milliseconds(shutdown_ms / num_procs));
-  base::UmaHistogramCounts100("Shutdown.renderers.total", num_procs);
-  base::UmaHistogramCounts100("Shutdown.renderers.slow", num_procs_slow);
+  base::UmaHistogramCounts100("Shutdown.Renderers.Total", num_procs);
+  base::UmaHistogramCounts100("Shutdown.Renderers.Slow", num_procs_slow);
 }
 
 void ReadLastShutdownInfo() {
diff --git a/chrome/browser/lifetime/browser_shutdown_browsertest.cc b/chrome/browser/lifetime/browser_shutdown_browsertest.cc
index a334d89..127ac57 100644
--- a/chrome/browser/lifetime/browser_shutdown_browsertest.cc
+++ b/chrome/browser/lifetime/browser_shutdown_browsertest.cc
@@ -80,23 +80,13 @@
   BrowserList::RemoveObserver(&closing_observer);
 }
 
-// Flakes on Mac11.0: https://crbug.com/1259913
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_TwoBrowsersClosingShutdownHistograms \
-  DISABLED_TwoBrowsersClosingShutdownHistograms
-#else
-#define MAYBE_TwoBrowsersClosingShutdownHistograms \
-  TwoBrowsersClosingShutdownHistograms
-#endif
 IN_PROC_BROWSER_TEST_F(BrowserShutdownBrowserTest,
-                       MAYBE_TwoBrowsersClosingShutdownHistograms) {
+                       TwoBrowsersClosingShutdownHistograms) {
   histogram_tester_.ExpectUniqueSample(
       "Shutdown.ShutdownType",
       static_cast<int>(browser_shutdown::ShutdownType::kWindowClose), 1);
-  histogram_tester_.ExpectTotalCount("Shutdown.renderers.total", 1);
-  histogram_tester_.ExpectTotalCount("Shutdown.window_close.time2", 1);
-  histogram_tester_.ExpectTotalCount("Shutdown.window_close.time_per_process",
-                                     1);
+  histogram_tester_.ExpectTotalCount("Shutdown.Renderers.Total", 1);
+  histogram_tester_.ExpectTotalCount("Shutdown.WindowClose.Time", 1);
 }
 #else
 // On Chrome OS, the shutdown accelerator is handled by Ash and requires
diff --git a/chrome/browser/login_detection/login_detection_browsertest.cc b/chrome/browser/login_detection/login_detection_browsertest.cc
index 9ccc43e..e54c9902 100644
--- a/chrome/browser/login_detection/login_detection_browsertest.cc
+++ b/chrome/browser/login_detection/login_detection_browsertest.cc
@@ -248,7 +248,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
   ExpectLoginDetectionTypeMetric(LoginDetectionType::kNoLogin, 0);
 }
diff --git a/chrome/browser/login_detection/login_detection_tab_helper.cc b/chrome/browser/login_detection/login_detection_tab_helper.cc
index 3de3f25..ba38574 100644
--- a/chrome/browser/login_detection/login_detection_tab_helper.cc
+++ b/chrome/browser/login_detection/login_detection_tab_helper.cc
@@ -59,7 +59,8 @@
     : content::WebContentsObserver(web_contents),
       content::WebContentsUserData<LoginDetectionTabHelper>(*web_contents),
       oauth_login_detector_(std::make_unique<OAuthLoginDetector>()),
-      ukm_source_id_(web_contents->GetMainFrame()->GetPageUkmSourceId()) {
+      ukm_source_id_(
+          web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId()) {
   DCHECK(IsLoginDetectionFeatureEnabled());
 }
 
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
index f1b322b..52e6c943 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service.cc
@@ -110,7 +110,7 @@
       contents->IncrementCapturerCount(gfx::Size(), /*stay_hidden=*/true,
                                        /*stay_awake=*/true);
   content::RenderFrameHost* rfh =
-      GetRootRenderFrameHost(contents->GetMainFrame(), *url);
+      GetRootRenderFrameHost(contents->GetPrimaryMainFrame(), *url);
   if (in_memory) {
     CaptureTabInternal(tab_id, rfh->GetFrameTreeNodeId(), rfh->GetGlobalId(),
                        clip_x, clip_y, clip_width, clip_height, in_memory,
@@ -152,7 +152,7 @@
   // There is a small chance RenderFrameHost may be destroyed when the UI thread
   // is used to create the directory.  By doing a lookup for the RenderFrameHost
   // and comparing it to the WebContent, we can ensure that the content is still
-  // available for capture and WebContents::GetMainFrame did not return a
+  // available for capture and WebContents::GetPrimaryMainFrame did not return a
   // defunct pointer.
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id);
   if (!contents || !rfh || contents->IsBeingDestroyed() || !rfh->IsActive()) {
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
index b3b1198d..b2dd789 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
@@ -124,7 +124,7 @@
 
   void OverrideInterface(MockPaintPreviewRecorder* recorder) {
     blink::AssociatedInterfaceProvider* remote_interfaces =
-        web_contents()->GetMainFrame()->GetRemoteAssociatedInterfaces();
+        web_contents()->GetPrimaryMainFrame()->GetRemoteAssociatedInterfaces();
     remote_interfaces->OverrideBinderForTesting(
         paint_preview::mojom::PaintPreviewRecorder::Name_,
         base::BindRepeating(&MockPaintPreviewRecorder::BindRequest,
diff --git a/chrome/browser/media/autoplay_metrics_browsertest.cc b/chrome/browser/media/autoplay_metrics_browsertest.cc
index 086b416..77a5e05e 100644
--- a/chrome/browser/media/autoplay_metrics_browsertest.cc
+++ b/chrome/browser/media/autoplay_metrics_browsertest.cc
@@ -80,7 +80,7 @@
       embedded_test_server()->GetURL("bar.com", "/media/autoplay_iframe.html"));
 
   // Navigate main frame, try play.
-  NavigateFrameAndWait(web_contents()->GetMainFrame(), main_url);
+  NavigateFrameAndWait(web_contents()->GetPrimaryMainFrame(), main_url);
   TryAutoplay(test_ukm_recorder, web_contents());
 
   // Check that we recorded a UKM event using the main frame URL.
@@ -150,7 +150,7 @@
   }
 
   // Navigate top frame, try play.
-  NavigateFrameAndWait(web_contents()->GetMainFrame(), foo_url);
+  NavigateFrameAndWait(web_contents()->GetPrimaryMainFrame(), foo_url);
   TryAutoplay(test_ukm_recorder, web_contents());
 
   // Check that we recorded a UKM event using the main frame URL.
diff --git a/chrome/browser/media/cast_mirroring_service_host.cc b/chrome/browser/media/cast_mirroring_service_host.cc
index c84a0cee..e533698 100644
--- a/chrome/browser/media/cast_mirroring_service_host.cc
+++ b/chrome/browser/media/cast_mirroring_service_host.cc
@@ -114,8 +114,9 @@
     return media_id;
   media_id.type = content::DesktopMediaID::TYPE_WEB_CONTENTS;
   media_id.web_contents_id = content::WebContentsMediaCaptureId(
-      contents->GetMainFrame()->GetProcess()->GetID(),
-      contents->GetMainFrame()->GetRoutingID(), true /* disable_local_echo */);
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      contents->GetPrimaryMainFrame()->GetRoutingID(),
+      true /* disable_local_echo */);
   return media_id;
 }
 
@@ -156,8 +157,8 @@
     const content::DesktopMediaID media_id =
         content::DesktopStreamsRegistry::GetInstance()->RequestMediaForStreamId(
             desktop_stream_id,
-            initiator_contents->GetMainFrame()->GetProcess()->GetID(),
-            initiator_contents->GetMainFrame()->GetRoutingID(),
+            initiator_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+            initiator_contents->GetPrimaryMainFrame()->GetRoutingID(),
             url::Origin::Create(initiator_contents->GetVisibleURL()),
             &original_extension_name, content::kRegistryStreamTypeDesktop);
     mojo::MakeSelfOwnedReceiver(
diff --git a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
index 45f7962..0ff7341 100644
--- a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
+++ b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
@@ -60,7 +60,7 @@
   DCHECK(target_web_contents);
   content::DesktopMediaID media_id;
   content::RenderFrameHost* const main_frame =
-      target_web_contents->GetMainFrame();
+      target_web_contents->GetPrimaryMainFrame();
   const int process_id = main_frame->GetProcess()->GetID();
   const int frame_id = main_frame->GetRoutingID();
   media_id.type = content::DesktopMediaID::TYPE_WEB_CONTENTS;
diff --git a/chrome/browser/media/cdm_document_service_impl_test.cc b/chrome/browser/media/cdm_document_service_impl_test.cc
index 07f25f9..a6e7634 100644
--- a/chrome/browser/media/cdm_document_service_impl_test.cc
+++ b/chrome/browser/media/cdm_document_service_impl_test.cc
@@ -79,7 +79,7 @@
       ASSERT_TRUE(cdm_document_service_.Unbind());
     NavigateAndCommit(url);
     CdmDocumentServiceImpl::Create(
-        web_contents()->GetMainFrame(),
+        web_contents()->GetPrimaryMainFrame(),
         cdm_document_service_.BindNewPipeAndPassReceiver());
   }
 
@@ -116,8 +116,10 @@
 
     DictionaryPrefUpdate update(user_prefs, prefs::kMediaCdmOriginData);
     base::Value* dict = update.Get();
-    const std::string serialized_origin =
-        web_contents()->GetMainFrame()->GetLastCommittedOrigin().Serialize();
+    const std::string serialized_origin = web_contents()
+                                              ->GetPrimaryMainFrame()
+                                              ->GetLastCommittedOrigin()
+                                              .Serialize();
     dict->SetKey(serialized_origin, std::move(entry));
   }
 
diff --git a/chrome/browser/media/defer_background_media_browsertest.cc b/chrome/browser/media/defer_background_media_browsertest.cc
index 9cf9f3f..23e94c2 100644
--- a/chrome/browser/media/defer_background_media_browsertest.cc
+++ b/chrome/browser/media/defer_background_media_browsertest.cc
@@ -27,8 +27,8 @@
   ASSERT_EQ(2, browser()->tab_strip_model()->count());
   content::WebContents* background_contents =
       browser()->tab_strip_model()->GetWebContentsAt(1);
-  EXPECT_TRUE(
-      content::WaitForRenderFrameReady(background_contents->GetMainFrame()));
+  EXPECT_TRUE(content::WaitForRenderFrameReady(
+      background_contents->GetPrimaryMainFrame()));
   EXPECT_NE(background_contents,
             browser()->tab_strip_model()->GetActiveWebContents());
 
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc
index 0ff72d2..90f95eb0 100644
--- a/chrome/browser/media/media_engagement_browsertest.cc
+++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -978,7 +978,7 @@
   ASSERT_TRUE(embedded_test_server()->Start());
 
   MockAutoplayConfigurationClient client;
-  OverrideInterface(GetWebContents()->GetMainFrame(), &client);
+  OverrideInterface(GetWebContents()->GetPrimaryMainFrame(), &client);
 
   const GURL& initial_url = embedded_test_server()->GetURL("/empty.html");
   SetScores(url::Origin::Create(initial_url), 24, 20);
@@ -1046,7 +1046,7 @@
   ASSERT_TRUE(embedded_test_server()->Start());
 
   MockAutoplayConfigurationClient client;
-  OverrideInterface(GetWebContents()->GetMainFrame(), &client);
+  OverrideInterface(GetWebContents()->GetPrimaryMainFrame(), &client);
 
   const GURL& initial_url =
       embedded_test_server()->GetURL("a.com", "/empty.html");
@@ -1063,7 +1063,7 @@
       embedded_test_server()->GetURL("b.com", "/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   // AddAutoplayFlags should be called on the fenced frame.
diff --git a/chrome/browser/media/media_engagement_contents_observer_unittest.cc b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
index 35534d9..526d88c 100644
--- a/chrome/browser/media/media_engagement_contents_observer_unittest.cc
+++ b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
@@ -1401,7 +1401,7 @@
 
   // Activate the prerendered page.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      url, web_contents()->GetMainFrame());
+      url, web_contents()->GetPrimaryMainFrame());
   EXPECT_EQ(prerender_frame->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kActive);
   EXPECT_EQ(0u, GetAudioContextPlayersCount());
diff --git a/chrome/browser/media/platform_verification_chromeos_unittest.cc b/chrome/browser/media/platform_verification_chromeos_unittest.cc
index 768d299..efcf853 100644
--- a/chrome/browser/media/platform_verification_chromeos_unittest.cc
+++ b/chrome/browser/media/platform_verification_chromeos_unittest.cc
@@ -33,14 +33,14 @@
 // Tests the basic success case.
 TEST_F(PlatformVerificationChromeOSTest, Success) {
   EXPECT_TRUE(platform_verification::PerformBrowserChecks(
-      web_contents()->GetMainFrame()));
+      web_contents()->GetPrimaryMainFrame()));
 }
 
 TEST_F(PlatformVerificationChromeOSTest, BadURL) {
   GURL url("badurl");
   NavigateAndCommit(url);
   EXPECT_FALSE(platform_verification::PerformBrowserChecks(
-      web_contents()->GetMainFrame()));
+      web_contents()->GetPrimaryMainFrame()));
 }
 
 TEST_F(PlatformVerificationChromeOSTest, IncognitoProfile) {
@@ -53,7 +53,7 @@
       content::WebContentsTester::For(web_contents.get());
   tester->NavigateAndCommit(GetTestURL());
   EXPECT_FALSE(platform_verification::PerformBrowserChecks(
-      web_contents.get()->GetMainFrame()));
+      web_contents.get()->GetPrimaryMainFrame()));
 }
 
 TEST_F(PlatformVerificationChromeOSTest, ContentSettings) {
@@ -65,7 +65,7 @@
       ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, CONTENT_SETTING_BLOCK);
 
   EXPECT_FALSE(platform_verification::PerformBrowserChecks(
-      web_contents()->GetMainFrame()));
+      web_contents()->GetPrimaryMainFrame()));
 }
 
 }  // namespace
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
index 6126b001..b37174d 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -987,7 +987,8 @@
   PendingStreamRequest& request = *pending_stream_request_;
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   DCHECK(web_contents);
-  content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* const main_frame =
+      web_contents->GetPrimaryMainFrame();
   request.render_process_id = main_frame->GetProcess()->GetID();
   request.render_frame_id = main_frame->GetRoutingID();
   request.origin = url::Origin::Create(web_contents->GetVisibleURL());
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc b/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc
index 68e3e03..b43dd3a 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc
@@ -29,7 +29,8 @@
 // static
 void MediaRouterMojoMetrics::RecordTabMirroringMetrics(
     content::WebContents* web_contents) {
-  ukm::SourceId source_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   WebContentsAudioState audio_state = WebContentsAudioState::kWasNeverAudible;
   if (web_contents->IsCurrentlyAudible()) {
     audio_state = WebContentsAudioState::kIsCurrentlyAudible;
@@ -46,7 +47,8 @@
 void MediaRouterMojoMetrics::RecordSiteInitiatedMirroringStarted(
     content::WebContents* web_contents,
     const MediaSource& media_source) {
-  ukm::SourceId source_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   auto cast_source = CastMediaSource::FromMediaSource(media_source);
   if (cast_source) {
     ukm::builders::MediaRouter_SiteInitiatedMirroringStarted(source_id)
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
index d466e6c..fa87d62 100644
--- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
@@ -237,7 +237,8 @@
   }
 
   void SetMainFrame() {
-    content::RenderFrameHost* main_frame = GetWebContents()->GetMainFrame();
+    content::RenderFrameHost* main_frame =
+        GetWebContents()->GetPrimaryMainFrame();
     ASSERT_TRUE(main_frame);
     main_frame_process_id_ = main_frame->GetProcess()->GetID();
     main_frame_routing_id_ = main_frame->GetRoutingID();
diff --git a/chrome/browser/media/unified_autoplay_browsertest.cc b/chrome/browser/media/unified_autoplay_browsertest.cc
index 2ea4cf52..e34371d 100644
--- a/chrome/browser/media/unified_autoplay_browsertest.cc
+++ b/chrome/browser/media/unified_autoplay_browsertest.cc
@@ -116,7 +116,7 @@
   void SetAutoplayForceAllowFlag(const GURL& url) {
     mojo::AssociatedRemote<blink::mojom::AutoplayConfigurationClient> client;
     GetWebContents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->GetRemoteAssociatedInterfaces()
         ->GetInterface(&client);
     client->AddAutoplayFlags(url::Origin::Create(url),
@@ -144,11 +144,11 @@
         is_renderer_initiated, from_context_menu);
 
     open_url_params.initiator_origin =
-        active_contents->GetMainFrame()->GetLastCommittedOrigin();
+        active_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
     open_url_params.source_render_process_id =
-        active_contents->GetMainFrame()->GetProcess()->GetID();
+        active_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
     open_url_params.source_render_frame_id =
-        active_contents->GetMainFrame()->GetRoutingID();
+        active_contents->GetPrimaryMainFrame()->GetRoutingID();
     open_url_params.user_gesture = user_gesture;
 
     return active_contents->OpenURL(open_url_params);
@@ -458,7 +458,7 @@
   }
 
   content::RenderFrameHost* main_frame() const {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   content::RenderFrameHost* first_child() const {
diff --git a/chrome/browser/media/webrtc/capture_handle_browsertest.cc b/chrome/browser/media/webrtc/capture_handle_browsertest.cc
index 204cdcf..9db2e3b 100644
--- a/chrome/browser/media/webrtc/capture_handle_browsertest.cc
+++ b/chrome/browser/media/webrtc/capture_handle_browsertest.cc
@@ -74,7 +74,8 @@
 
   std::string origin_str;
   if (expose_origin) {
-    const auto origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+    const auto origin =
+        web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
     origin_str =
         base::StringPrintf(",\"origin\":\"%s\"", origin.Serialize().c_str());
   }
@@ -92,20 +93,21 @@
 
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "captureOtherTab();", &script_result));
+        web_contents->GetPrimaryMainFrame(), "captureOtherTab();",
+        &script_result));
     EXPECT_EQ(script_result, "capture-success");
   }
 
   void StartCapturingFromEmbeddedFrame() {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "captureOtherTabFromEmbeddedFrame();",
-        &script_result));
+        web_contents->GetPrimaryMainFrame(),
+        "captureOtherTabFromEmbeddedFrame();", &script_result));
     EXPECT_EQ(script_result, "embedded-capture-success");
   }
 
   url::Origin GetOrigin() const {
-    return web_contents->GetMainFrame()->GetLastCommittedOrigin();
+    return web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   }
 
   std::string GetOriginAsString() const { return GetOrigin().Serialize(); }
@@ -116,7 +118,7 @@
       const std::vector<std::string>& permitted_origins) {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StringPrintf(
             "callSetCaptureHandleConfig(%s, \"%s\", %s);",
             expose_origin ? "true" : "false", handle.c_str(),
@@ -131,22 +133,23 @@
   std::string ReadCaptureHandle() {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "readCaptureHandle();", &script_result));
+        web_contents->GetPrimaryMainFrame(), "readCaptureHandle();",
+        &script_result));
     return script_result;
   }
 
   std::string ReadCaptureHandleInEmbeddedFrame() {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "readCaptureHandleInEmbeddedFrame();",
-        &script_result));
+        web_contents->GetPrimaryMainFrame(),
+        "readCaptureHandleInEmbeddedFrame();", &script_result));
     return script_result;
   }
 
   void Navigate(GURL url, bool expect_handle_reset = false) {
     std::string script_result;
     ASSERT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StringPrintf("clickLinkToUrl(\"%s\");", url.spec().c_str()),
         &script_result));
     ASSERT_EQ(script_result, "link-success");
@@ -159,14 +162,15 @@
   std::string LastEvent() {
     std::string script_result = "error-not-modified";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "readLastEvent();", &script_result));
+        web_contents->GetPrimaryMainFrame(), "readLastEvent();",
+        &script_result));
     return script_result;
   }
 
   std::string LastEmbeddedEvent() {
     std::string script_result = "error-not-modified";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "readLastEmbeddedEvent();",
+        web_contents->GetPrimaryMainFrame(), "readLastEmbeddedEvent();",
         &script_result));
     return script_result;
   }
@@ -174,7 +178,7 @@
   void StartEmbeddingFrame(const GURL& url) {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StringPrintf("startEmbeddingFrame('%s');", url.spec().c_str()),
         &script_result));
     EXPECT_EQ(script_result, "embedding-done");
@@ -298,7 +302,7 @@
     if (self_capture) {
       std::string script_result;
       EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-          web_contents->GetMainFrame(),
+          web_contents->GetPrimaryMainFrame(),
           base::StringPrintf("setTitle(\"%s\");", kCapturedTabTitle),
           &script_result));
       EXPECT_EQ(script_result, "title-changed");
@@ -613,8 +617,8 @@
   // In-document navigation does not change the capture handle (config).
   std::string navigation_result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      captured_tab.web_contents->GetMainFrame(), "clickLinkToPageBottom();",
-      &navigation_result));
+      captured_tab.web_contents->GetPrimaryMainFrame(),
+      "clickLinkToPageBottom();", &navigation_result));
   ASSERT_EQ(navigation_result, "navigated");
 
   // No event was fired (verified in teardown) and getCaptureHandle returns the
diff --git a/chrome/browser/media/webrtc/conditional_focus_browsertest.cc b/chrome/browser/media/webrtc/conditional_focus_browsertest.cc
index af7e20e..a3345a38 100644
--- a/chrome/browser/media/webrtc/conditional_focus_browsertest.cc
+++ b/chrome/browser/media/webrtc/conditional_focus_browsertest.cc
@@ -124,7 +124,7 @@
     std::string script_result;
     // TODO(crbug.com/1243764): Use EvalJs() instead.
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        capturing_tab_->GetMainFrame(),
+        capturing_tab_->GetPrimaryMainFrame(),
         base::StringPrintf("captureOtherTab(%d, \"%s\", %s);", busy_wait_ms,
                            ToString(focus_enum_value),
                            on_correct_microtask ? "true" : "false"),
@@ -156,7 +156,7 @@
     std::string script_result;
     // TODO(crbug.com/1243764): Use EvalJs() instead.
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        capturing_tab_->GetMainFrame(), "callFocusAndExpectError();",
+        capturing_tab_->GetPrimaryMainFrame(), "callFocusAndExpectError();",
         &script_result));
     EXPECT_EQ(script_result, expected_error);
   }
@@ -286,7 +286,7 @@
   // TODO(crbug.com/1243764): Use EvalJs() instead.
   std::string script_result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      capturing_tab_->GetMainFrame(), "captureCloneAndFocusClone();",
+      capturing_tab_->GetPrimaryMainFrame(), "captureCloneAndFocusClone();",
       &script_result));
   EXPECT_EQ(
       script_result,
diff --git a/chrome/browser/media/webrtc/current_tab_desktop_media_list.cc b/chrome/browser/media/webrtc/current_tab_desktop_media_list.cc
index e876f1e..b1f44e2b 100644
--- a/chrome/browser/media/webrtc/current_tab_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/current_tab_desktop_media_list.cc
@@ -88,8 +88,8 @@
       media_id_(content::DesktopMediaID::TYPE_WEB_CONTENTS,
                 content::DesktopMediaID::kNullId,
                 content::WebContentsMediaCaptureId(
-                    web_contents->GetMainFrame()->GetProcess()->GetID(),
-                    web_contents->GetMainFrame()->GetRoutingID())),
+                    web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+                    web_contents->GetPrimaryMainFrame()->GetRoutingID())),
       thumbnail_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::USER_VISIBLE})) {
   DCHECK(web_contents);
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
index 1aa2665..dd67a87 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -91,7 +91,7 @@
     return base::UTF8ToUTF16(extension->name());
 
   return url_formatter::FormatOriginForSecurityDisplay(
-      web_contents->GetMainFrame()->GetLastCommittedOrigin(),
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
       url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
 }
 
@@ -409,7 +409,7 @@
           content::RenderFrameHost::FromID(request.render_process_id,
                                            request.render_frame_id));
   content::RenderFrameHost* const main_frame =
-      web_contents_for_stream ? web_contents_for_stream->GetMainFrame()
+      web_contents_for_stream ? web_contents_for_stream->GetPrimaryMainFrame()
                               : nullptr;
   if (main_frame) {
     media_id =
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
index fcb7a46..30eaaae4 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
@@ -72,9 +72,10 @@
         features::kMacSystemScreenCapturePermissionCheck);
 #endif
     content::MediaStreamRequest request(
-        web_contents()->GetMainFrame()->GetProcess()->GetID(),
-        web_contents()->GetMainFrame()->GetRoutingID(), /*page_request_id=*/0,
-        origin, /*user_gesture=*/false, blink::MEDIA_GENERATE_STREAM,
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+        web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
+        /*page_request_id=*/0, origin, /*user_gesture=*/false,
+        blink::MEDIA_GENERATE_STREAM,
         /*requested_audio_device_id=*/std::string(), requested_video_device_id,
         blink::mojom::MediaStreamType::NO_SERVICE,
         blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE,
@@ -345,8 +346,8 @@
   const GURL origin(kOrigin);
   const std::string id =
       content::DesktopStreamsRegistry::GetInstance()->RegisterStream(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID(),
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
           url::Origin::Create(origin),
           content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
                                   content::DesktopMediaID::kFakeId),
@@ -508,8 +509,8 @@
 
   const std::string id =
       content::DesktopStreamsRegistry::GetInstance()->RegisterStream(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID(),
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
           url::Origin::Create(GURL(kOrigin)),
           content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
                                   content::DesktopMediaID::kFakeId),
@@ -541,8 +542,8 @@
 
   const std::string id =
       content::DesktopStreamsRegistry::GetInstance()->RegisterStream(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID(),
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
           url::Origin::Create(GURL(kOrigin)),
           content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
                                   content::DesktopMediaID::kFakeId),
diff --git a/chrome/browser/media/webrtc/desktop_capture_devices_util.cc b/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
index e2cabd06..7333be5 100644
--- a/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
@@ -66,7 +66,7 @@
 
   // Observing CaptureHandle when either the capturing or the captured party
   // is incognito is disallowed, except for self-capture.
-  if (capturer->GetMainFrame() != captured->GetMainFrame()) {
+  if (capturer->GetPrimaryMainFrame() != captured->GetPrimaryMainFrame()) {
     if (capturer->GetBrowserContext()->IsOffTheRecord() ||
         captured->GetBrowserContext()->IsOffTheRecord()) {
       return nullptr;
@@ -80,7 +80,7 @@
 
   auto result = media::mojom::CaptureHandle::New();
   if (captured_config.expose_origin) {
-    result->origin = captured->GetMainFrame()->GetLastCommittedOrigin();
+    result->origin = captured->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   }
   result->capture_handle = captured_config.capture_handle;
 
@@ -178,9 +178,9 @@
   // dialog for DISPLAY_VIDEO_CAPTURE_THIS_TAB could still return something
   // other than the current tab - be it a screen, window, or another tab.
   if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS &&
-      web_contents->GetMainFrame()->GetProcess()->GetID() ==
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID() ==
           media_id.web_contents_id.render_process_id &&
-      web_contents->GetMainFrame()->GetRoutingID() ==
+      web_contents->GetPrimaryMainFrame()->GetRoutingID() ==
           media_id.web_contents_id.main_render_frame_id) {
     return "current-";
   }
@@ -254,8 +254,8 @@
   if (display_notification) {
     if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
       content::GlobalRenderFrameHostId capturer_id;
-      if (web_contents && web_contents->GetMainFrame()) {
-        capturer_id = web_contents->GetMainFrame()->GetGlobalId();
+      if (web_contents && web_contents->GetPrimaryMainFrame()) {
+        capturer_id = web_contents->GetPrimaryMainFrame()->GetGlobalId();
       }
       notification_ui = TabSharingUI::Create(
           capturer_id, media_id, application_title,
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc
index e160d1d..c1cda77 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -49,7 +49,7 @@
 // Helper function to get the title of the calling application.
 std::u16string GetApplicationTitle(content::WebContents* web_contents) {
   return url_formatter::FormatOriginForSecurityDisplay(
-      web_contents->GetMainFrame()->GetLastCommittedOrigin(),
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
       url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
 }
 
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
index 48b93fd..ddf19262 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -51,7 +51,7 @@
 
   content::WebContentsMediaCaptureId GetWebContentsMediaCaptureId() {
     return content::WebContentsMediaCaptureId(
-        web_contents()->GetMainFrame()->GetProcess()->GetID(), 1);
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(), 1);
   }
 
   FakeDesktopMediaPickerFactory::TestFlags MakePickerTestFlags(
@@ -69,8 +69,8 @@
 
   content::MediaStreamRequest MakeRequest(bool request_audio) {
     return content::MediaStreamRequest(
-        web_contents()->GetMainFrame()->GetProcess()->GetID(),
-        web_contents()->GetMainFrame()->GetRoutingID(), 0,
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+        web_contents()->GetPrimaryMainFrame()->GetRoutingID(), 0,
         GURL("http://origin/"), false, blink::MEDIA_GENERATE_STREAM,
         std::string(), std::string(),
         request_audio ? blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE
@@ -345,8 +345,9 @@
 
 TEST_F(DisplayMediaAccessHandlerTest, UpdateMediaRequestStateWithClosing) {
   const int render_process_id =
-      web_contents()->GetMainFrame()->GetProcess()->GetID();
-  const int render_frame_id = web_contents()->GetMainFrame()->GetRoutingID();
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+  const int render_frame_id =
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID();
   const int page_request_id = 0;
   const blink::mojom::MediaStreamType video_stream_type =
       blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE;
@@ -383,8 +384,9 @@
 
 TEST_F(DisplayMediaAccessHandlerTest, CorrectHostAsksForPermissions) {
   const int render_process_id =
-      web_contents()->GetMainFrame()->GetProcess()->GetID();
-  const int render_frame_id = web_contents()->GetMainFrame()->GetRoutingID();
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+  const int render_frame_id =
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID();
   const int page_request_id = 0;
   const blink::mojom::MediaStreamType video_stream_type =
       blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE;
@@ -417,8 +419,9 @@
 
 TEST_F(DisplayMediaAccessHandlerTest, CorrectHostAsksForPermissionsNormalURLs) {
   const int render_process_id =
-      web_contents()->GetMainFrame()->GetProcess()->GetID();
-  const int render_frame_id = web_contents()->GetMainFrame()->GetRoutingID();
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+  const int render_frame_id =
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID();
   const int page_request_id = 0;
   const blink::mojom::MediaStreamType video_stream_type =
       blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE;
@@ -454,10 +457,10 @@
                  false /* expect_audio */, content::DesktopMediaID(),
                  true /* cancelled */}});
   content::MediaStreamRequest request(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(), 0, GURL("http://origin/"),
-      false, blink::MEDIA_GENERATE_STREAM, std::string(), std::string(),
-      blink::mojom::MediaStreamType::NO_SERVICE,
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(), 0,
+      GURL("http://origin/"), false, blink::MEDIA_GENERATE_STREAM,
+      std::string(), std::string(), blink::mojom::MediaStreamType::NO_SERVICE,
       blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE,
       /*disable_local_echo=*/false, /*request_pan_tilt_zoom_permission=*/false);
   content::MediaResponseCallback callback;
@@ -494,8 +497,8 @@
   base::RunLoop wait_loop[kTestFlagCount];
   for (size_t i = 0; i < kTestFlagCount; ++i) {
     content::MediaStreamRequest request(
-        web_contents()->GetMainFrame()->GetProcess()->GetID(),
-        web_contents()->GetMainFrame()->GetRoutingID(), 0,
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+        web_contents()->GetPrimaryMainFrame()->GetRoutingID(), 0,
         GURL("http://origin/"), false, blink::MEDIA_GENERATE_STREAM,
         std::string(), std::string(), blink::mojom::MediaStreamType::NO_SERVICE,
         blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE,
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc b/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc
index 38408a6..cb163b9 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc
@@ -72,7 +72,7 @@
 
   PageSpecificContentSettings* GetContentSettings() {
     return PageSpecificContentSettings::GetForFrame(
-        GetWebContents()->GetMainFrame());
+        GetWebContents()->GetPrimaryMainFrame());
   }
 
   const std::string& example_audio_id() const { return example_audio_id_; }
@@ -159,17 +159,20 @@
         video_id.empty() ? blink::mojom::MediaStreamType::NO_SERVICE
                          : blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE;
     if (!GetWebContents()
-             ->GetMainFrame()
+             ->GetPrimaryMainFrame()
              ->GetLastCommittedOrigin()
              .GetURL()
              .is_empty()) {
-      EXPECT_EQ(
-          example_url().DeprecatedGetOriginAsURL(),
-          GetWebContents()->GetMainFrame()->GetLastCommittedOrigin().GetURL());
+      EXPECT_EQ(example_url().DeprecatedGetOriginAsURL(),
+                GetWebContents()
+                    ->GetPrimaryMainFrame()
+                    ->GetLastCommittedOrigin()
+                    .GetURL());
     }
     int render_process_id =
-        GetWebContents()->GetMainFrame()->GetProcess()->GetID();
-    int render_frame_id = GetWebContents()->GetMainFrame()->GetRoutingID();
+        GetWebContents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+    int render_frame_id =
+        GetWebContents()->GetPrimaryMainFrame()->GetRoutingID();
     return content::MediaStreamRequest(
         render_process_id, render_frame_id, 0,
         example_url().DeprecatedGetOriginAsURL(), false, request_type, audio_id,
@@ -1020,7 +1023,7 @@
   content::NavigateIframeToURL(GetWebContents(), "test",
                                GURL(cross_origin_url));
   content::RenderFrameHost* child_frame =
-      ChildFrameAt(GetWebContents()->GetMainFrame(), 0);
+      ChildFrameAt(GetWebContents()->GetPrimaryMainFrame(), 0);
 
   content::MediaStreamRequest request =
       CreateRequest(example_audio_id(), example_video_id(), false);
@@ -1052,7 +1055,7 @@
   content::NavigateIframeToURL(GetWebContents(), "test",
                                GURL(cross_origin_url));
   content::RenderFrameHost* child_frame =
-      ChildFrameAt(GetWebContents()->GetMainFrame(), 0);
+      ChildFrameAt(GetWebContents()->GetPrimaryMainFrame(), 0);
 
   content::MediaStreamRequest request =
       CreateRequest(std::string(), example_video_id(), false);
diff --git a/chrome/browser/media/webrtc/media_stream_focus_delegate.cc b/chrome/browser/media/webrtc/media_stream_focus_delegate.cc
index 88619a0f..193ce73 100644
--- a/chrome/browser/media/webrtc/media_stream_focus_delegate.cc
+++ b/chrome/browser/media/webrtc/media_stream_focus_delegate.cc
@@ -244,7 +244,8 @@
 
 bool MediaStreamFocusDelegate::BadMessage(
     bad_message::BadMessageReason reason) {
-  content::RenderFrameHost* const rfh = capturing_web_contents_->GetMainFrame();
+  content::RenderFrameHost* const rfh =
+      capturing_web_contents_->GetPrimaryMainFrame();
   if (rfh) {
     bad_message::ReceivedBadMessage(rfh->GetProcess(), reason);
   }
diff --git a/chrome/browser/media/webrtc/media_stream_focus_delegate_unittest.cc b/chrome/browser/media/webrtc/media_stream_focus_delegate_unittest.cc
index f9d78107..47361fdf 100644
--- a/chrome/browser/media/webrtc/media_stream_focus_delegate_unittest.cc
+++ b/chrome/browser/media/webrtc/media_stream_focus_delegate_unittest.cc
@@ -34,8 +34,8 @@
         content::DesktopMediaID::TYPE_WEB_CONTENTS,
         content::DesktopMediaID::kNullId,
         content::WebContentsMediaCaptureId(
-            tab->GetMainFrame()->GetProcess()->GetID(),
-            tab->GetMainFrame()->GetRoutingID()));
+            tab->GetPrimaryMainFrame()->GetProcess()->GetID(),
+            tab->GetPrimaryMainFrame()->GetRoutingID()));
   }
 
   void SetFocus(const content::DesktopMediaID& media_id,
diff --git a/chrome/browser/media/webrtc/region_capture_browsertest.cc b/chrome/browser/media/webrtc/region_capture_browsertest.cc
index baa9ac6..88032dc 100644
--- a/chrome/browser/media/webrtc/region_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/region_capture_browsertest.cc
@@ -90,7 +90,7 @@
   void StartEmbeddingFrame(const GURL& url) {
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StringPrintf("startEmbeddingFrame('%s');", url.spec().c_str()),
         &script_result));
     EXPECT_EQ(script_result, "embedding-done");
@@ -102,7 +102,8 @@
 
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "startCapture();", &script_result));
+        web_contents->GetPrimaryMainFrame(), "startCapture();",
+        &script_result));
     EXPECT_EQ(script_result, "capture-success");
   }
 
@@ -112,7 +113,7 @@
 
     std::string script_result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(), "startCaptureFromEmbeddedFrame();",
+        web_contents->GetPrimaryMainFrame(), "startCaptureFromEmbeddedFrame();",
         &script_result));
     EXPECT_EQ(script_result, "embedded-capture-success");
   }
@@ -124,7 +125,7 @@
         (frame == Frame::kTopLevelDocument) ? "top" : "embedded";
     std::string script_result = "error-not-modified";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StrCat(
             {"produceCropId(\"", frame_js, "\", \"" + element_id + "\");"}),
         &script_result));
@@ -134,7 +135,7 @@
   std::string CropTo(const std::string& crop_id) {
     std::string script_result = "error-not-modified";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StrCat({"cropTo(\"", crop_id, "\");"}), &script_result));
     return script_result;
   }
@@ -145,7 +146,7 @@
         (frame == Frame::kTopLevelDocument) ? "top" : "embedded";
     std::string script_result = "error-not-modified";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         base::StrCat(
             {"createNewDivElement(\"", frame_js, "\", \"", div_id, "\");"}),
         &script_result));
diff --git a/chrome/browser/media/webrtc/same_origin_observer.cc b/chrome/browser/media/webrtc/same_origin_observer.cc
index bcd2583f..bdf1359 100644
--- a/chrome/browser/media/webrtc/same_origin_observer.cc
+++ b/chrome/browser/media/webrtc/same_origin_observer.cc
@@ -16,7 +16,7 @@
       on_same_origin_state_changed_(on_same_origin_state_changed) {
   DCHECK(observed_contents);
   is_same_origin_ = reference_origin_.IsSameOriginWith(
-      observed_contents->GetMainFrame()->GetLastCommittedOrigin());
+      observed_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 SameOriginObserver::~SameOriginObserver() = default;
diff --git a/chrome/browser/media/webrtc/same_origin_observer_browsertest.cc b/chrome/browser/media/webrtc/same_origin_observer_browsertest.cc
index f32dafb7..85cdb5d 100644
--- a/chrome/browser/media/webrtc/same_origin_observer_browsertest.cc
+++ b/chrome/browser/media/webrtc/same_origin_observer_browsertest.cc
@@ -80,7 +80,7 @@
   // The same-origin state callback is not called by fenced frames.
   EXPECT_CALL(origin_state_callback_, Run).Times(0);
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       embedded_test_server()->GetURL("b.com", "/fenced_frames/title1.html")));
   testing::Mock::VerifyAndClearExpectations(&origin_state_callback_);
 }
diff --git a/chrome/browser/media/webrtc/tab_capture_access_handler.cc b/chrome/browser/media/webrtc/tab_capture_access_handler.cc
index 4828879..b822143 100644
--- a/chrome/browser/media/webrtc/tab_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/tab_capture_access_handler.cc
@@ -178,10 +178,11 @@
     // Use extension name as title for extensions and host/origin for drive-by
     // web.
     std::u16string application_title =
-        extension ? base::UTF8ToUTF16(extension->name())
-                  : url_formatter::FormatOriginForSecurityDisplay(
-                        web_contents->GetMainFrame()->GetLastCommittedOrigin(),
-                        url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
+        extension
+            ? base::UTF8ToUTF16(extension->name())
+            : url_formatter::FormatOriginForSecurityDisplay(
+                  web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+                  url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
     content::DesktopMediaID media_id(
         content::DesktopMediaID::TYPE_WEB_CONTENTS, /*id=*/0,
         content::WebContentsMediaCaptureId(request.render_process_id,
diff --git a/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc b/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
index cc7746058..f0ca643 100644
--- a/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
@@ -50,9 +50,10 @@
       blink::mojom::StreamDevices* devices_result,
       bool expect_result = true) {
     content::MediaStreamRequest request(
-        web_contents()->GetMainFrame()->GetProcess()->GetID(),
-        web_contents()->GetMainFrame()->GetRoutingID(), /*page_request_id=*/0,
-        GURL(kOrigin), /*user_gesture=*/false, blink::MEDIA_GENERATE_STREAM,
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+        web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
+        /*page_request_id=*/0, GURL(kOrigin), /*user_gesture=*/false,
+        blink::MEDIA_GENERATE_STREAM,
         /*requested_audio_device_id=*/std::string(),
         /*requested_video_device_id=*/std::string(),
         blink::mojom::MediaStreamType::NO_SERVICE,
@@ -96,8 +97,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID()));
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID()));
 
   extensions::TabCaptureRegistry::Get(profile())->AddRequest(
       web_contents(), /*extension_id=*/"", /*is_anonymous=*/false,
@@ -120,8 +121,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID()));
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID()));
 
   // Setup Data Leak Prevention restriction.
   policy::MockDlpContentManager mock_dlp_content_manager;
@@ -152,8 +153,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID()));
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID()));
 
   // Setup Data Leak Prevention restriction.
   policy::MockDlpContentManager mock_dlp_content_manager;
@@ -184,8 +185,8 @@
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
       content::WebContentsMediaCaptureId(
-          web_contents()->GetMainFrame()->GetProcess()->GetID(),
-          web_contents()->GetMainFrame()->GetRoutingID()));
+          web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+          web_contents()->GetPrimaryMainFrame()->GetRoutingID()));
 
   // Setup Data Leak Prevention restriction.
   policy::MockDlpContentManager mock_dlp_content_manager;
diff --git a/chrome/browser/media/webrtc/tab_desktop_media_list.cc b/chrome/browser/media/webrtc/tab_desktop_media_list.cc
index f02d85bf..8b0cf4f 100644
--- a/chrome/browser/media/webrtc/tab_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/tab_desktop_media_list.cc
@@ -196,7 +196,7 @@
   for (auto* contents : contents_list) {
     if (!includable_web_contents_filter_.Run(contents))
       continue;
-    content::RenderFrameHost* main_frame = contents->GetMainFrame();
+    content::RenderFrameHost* main_frame = contents->GetPrimaryMainFrame();
     DCHECK(main_frame);
     DesktopMediaID media_id(
         DesktopMediaID::TYPE_WEB_CONTENTS, DesktopMediaID::kNullId,
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
index 39dc655..eb6df96 100644
--- a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
+++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
@@ -156,7 +156,8 @@
   GetUserMedia(tab_contents, constraints);
   EXPECT_TRUE(observer.request_shown());
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   return kOkGotStream == result;
 }
 
@@ -169,7 +170,8 @@
           permissions::PermissionRequestManager::ACCEPT_ALL);
   GetUserMedia(tab_contents, constraints);
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   return kOkGotStream == result;
 }
 
@@ -189,7 +191,8 @@
   GetUserMedia(tab_contents, constraints);
   EXPECT_TRUE(observer.request_shown());
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   EXPECT_EQ(kFailedWithNotAllowedError, result);
 }
 
@@ -204,7 +207,8 @@
   EXPECT_TRUE(observer.request_shown());
   // A dismiss should be treated like a deny.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   EXPECT_EQ(kFailedWithNotAllowedError, result);
 }
 
@@ -226,7 +230,8 @@
   GetUserMedia(tab_contents, kAudioVideoCallConstraints);
   EXPECT_FALSE(observer.request_shown());
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   EXPECT_EQ(kOkGotStream, result);
 }
 
@@ -248,7 +253,8 @@
   GetUserMedia(tab_contents, kAudioVideoCallConstraints);
   EXPECT_FALSE(observer.request_shown());
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      tab_contents->GetPrimaryMainFrame(), "obtainGetUserMediaResult();",
+      &result));
   EXPECT_EQ(kFailedWithNotAllowedError, result);
 }
 
@@ -299,7 +305,7 @@
   GetUserMedia(new_tab, constraints);
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      new_tab->GetMainFrame(), "obtainGetUserMediaResult();", &result));
+      new_tab->GetPrimaryMainFrame(), "obtainGetUserMediaResult();", &result));
   EXPECT_EQ(kOkGotStream, result);
   return new_tab;
 }
diff --git a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
index fdf4ae8..84339608 100644
--- a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
@@ -49,7 +49,7 @@
 
 content::DesktopMediaID GetDesktopMediaIDForTab(Browser* browser, int tab) {
   content::RenderFrameHost* main_frame =
-      GetWebContents(browser, tab)->GetMainFrame();
+      GetWebContents(browser, tab)->GetPrimaryMainFrame();
   return content::DesktopMediaID(
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index b785352e..e36683c 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -108,7 +108,7 @@
                         bool is_tab_capture) {
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetDisplayMedia(%s, \"top-level-document\");",
                          constraints.c_str()),
       &result));
@@ -274,7 +274,7 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "waitVideoUnmuted();", &result));
+      tab->GetPrimaryMainFrame(), "waitVideoUnmuted();", &result));
   EXPECT_EQ(result, "unmuted");
 
   const policy::DlpContentRestrictionSet kScreenShareRestricted(
@@ -285,14 +285,14 @@
   content::WaitForLoadStop(tab);
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "waitVideoMuted();", &result));
+      tab->GetPrimaryMainFrame(), "waitVideoMuted();", &result));
   EXPECT_EQ(result, "muted");
 
   const policy::DlpContentRestrictionSet kEmptyRestrictionSet;
   helper.ChangeConfidentiality(tab, kEmptyRestrictionSet);
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "waitVideoUnmuted();", &result));
+      tab->GetPrimaryMainFrame(), "waitVideoUnmuted();", &result));
   EXPECT_EQ(result, "unmuted");
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -377,15 +377,15 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getDisplaySurfaceSetting();", &result));
+      tab->GetPrimaryMainFrame(), "getDisplaySurfaceSetting();", &result));
   EXPECT_EQ(result, test_config_.display_surface);
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getLogicalSurfaceSetting();", &result));
+      tab->GetPrimaryMainFrame(), "getLogicalSurfaceSetting();", &result));
   EXPECT_EQ(result, "true");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getCursorSetting();", &result));
+      tab->GetPrimaryMainFrame(), "getCursorSetting();", &result));
   EXPECT_EQ(result, "never");
 }
 
@@ -404,7 +404,7 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "hasAudioTrack();", &result));
+      tab->GetPrimaryMainFrame(), "hasAudioTrack();", &result));
   EXPECT_EQ(result, "true");
 }
 
@@ -427,11 +427,11 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getWidthSetting();", &result));
+      tab->GetPrimaryMainFrame(), "getWidthSetting();", &result));
   EXPECT_EQ(result, base::StringPrintf("%d", kMaxWidth));
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getFrameRateSetting();", &result));
+      tab->GetPrimaryMainFrame(), "getFrameRateSetting();", &result));
   EXPECT_EQ(result, base::StringPrintf("%d", kMaxFrameRate));
 }
 
@@ -506,7 +506,7 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      OpenTestPageInNewTab(kMainHtmlPage)->GetMainFrame(),
+      OpenTestPageInNewTab(kMainHtmlPage)->GetPrimaryMainFrame(),
       base::StringPrintf(
           "runGetDisplayMedia(%s, \"%s\");", constraints.c_str(),
           allowlisted_by_policy_ ? "allowedFrame" : "disallowedFrame"),
@@ -657,7 +657,7 @@
   // Verify that the video stream has ended.
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      capturing_tab->GetMainFrame(), "waitVideoEnded();", &result));
+      capturing_tab->GetPrimaryMainFrame(), "waitVideoEnded();", &result));
   EXPECT_EQ(result, "ended");
 }
 
@@ -699,8 +699,8 @@
   // Verify that the video hasn't been ended.
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      capturing_tab->GetMainFrame(), "returnToTest(video_track.readyState);",
-      &result));
+      capturing_tab->GetPrimaryMainFrame(),
+      "returnToTest(video_track.readyState);", &result));
   EXPECT_EQ(result, "live");
 }
 
@@ -743,7 +743,7 @@
     // Initiate the capture.
     std::string result;
     ASSERT_TRUE(content::ExecuteScriptAndExtractString(
-        tab_->GetMainFrame(),
+        tab_->GetPrimaryMainFrame(),
         "runGetDisplayMedia({video: true, audio: true}, "
         "\"top-level-document\");",
         &result));
@@ -776,21 +776,21 @@
   std::string GetVideoTrackType() {
     std::string result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        tab_->GetMainFrame(), "getVideoTrackType();", &result));
+        tab_->GetPrimaryMainFrame(), "getVideoTrackType();", &result));
     return result;
   }
 
   std::string GetVideoCloneTrackType() {
     std::string result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        tab_->GetMainFrame(), "getVideoCloneTrackType();", &result));
+        tab_->GetPrimaryMainFrame(), "getVideoCloneTrackType();", &result));
     return result;
   }
 
   bool HasAudioTrack() {
     std::string result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        tab_->GetMainFrame(), "hasAudioTrack();", &result));
+        tab_->GetPrimaryMainFrame(), "hasAudioTrack();", &result));
     EXPECT_TRUE(result == "true" || result == "false");
     return result == "true";
   }
@@ -798,7 +798,7 @@
   std::string GetAudioTrackType() {
     std::string result;
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-        tab_->GetMainFrame(), "getAudioTrackType();", &result));
+        tab_->GetPrimaryMainFrame(), "getAudioTrackType();", &result));
     return result;
   }
 
@@ -910,19 +910,21 @@
   EXPECT_TRUE(captured_tab->IsBeingCaptured());
   EXPECT_FALSE(other_tab->IsBeingCaptured());
   EXPECT_FALSE(capturing_tab->IsBeingCaptured());
-  EXPECT_EQ(GetSecondaryButtonLabel(captured_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    captured_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(captured_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              captured_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
   EXPECT_EQ(GetSecondaryButtonLabel(other_tab), kShareThisTabInsteadMessage);
-  EXPECT_EQ(GetSecondaryButtonLabel(capturing_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    capturing_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(capturing_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              capturing_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
 
   // Click the secondary button, i.e., the "Share this tab instead" button
   GetDelegate(other_tab)->Cancel();
@@ -940,14 +942,15 @@
             l10n_util::GetStringFUTF16(
                 IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
                 url_formatter::FormatOriginForSecurityDisplay(
-                    other_tab->GetMainFrame()->GetLastCommittedOrigin(),
+                    other_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
                     url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
-  EXPECT_EQ(GetSecondaryButtonLabel(capturing_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    capturing_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(capturing_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              capturing_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
 }
 
 IN_PROC_BROWSER_TEST_F(GetDisplayMediaChangeSourceBrowserTest,
@@ -967,19 +970,21 @@
   EXPECT_TRUE(captured_tab->IsBeingCaptured());
   EXPECT_FALSE(other_tab->IsBeingCaptured());
   EXPECT_FALSE(capturing_tab->IsBeingCaptured());
-  EXPECT_EQ(GetSecondaryButtonLabel(captured_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    captured_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(captured_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              captured_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
   EXPECT_EQ(GetSecondaryButtonLabel(other_tab), kShareThisTabInsteadMessage);
-  EXPECT_EQ(GetSecondaryButtonLabel(capturing_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    capturing_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(capturing_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              capturing_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
 
   browser()->tab_strip_model()->ActivateTabAt(
       browser()->tab_strip_model()->GetIndexOfWebContents(other_tab));
@@ -1003,19 +1008,21 @@
   EXPECT_TRUE(captured_tab->IsBeingCaptured());
   EXPECT_FALSE(other_tab->IsBeingCaptured());
   EXPECT_FALSE(capturing_tab->IsBeingCaptured());
-  EXPECT_EQ(GetSecondaryButtonLabel(captured_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    captured_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(captured_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              captured_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
   EXPECT_EQ(GetSecondaryButtonLabel(other_tab), kShareThisTabInsteadMessage);
-  EXPECT_EQ(GetSecondaryButtonLabel(capturing_tab),
-            l10n_util::GetStringFUTF16(
-                IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
-                url_formatter::FormatOriginForSecurityDisplay(
-                    capturing_tab->GetMainFrame()->GetLastCommittedOrigin(),
-                    url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
+  EXPECT_EQ(
+      GetSecondaryButtonLabel(capturing_tab),
+      l10n_util::GetStringFUTF16(
+          IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
+          url_formatter::FormatOriginForSecurityDisplay(
+              capturing_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
+              url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)));
 }
 
 #endif
diff --git a/chrome/browser/media/webrtc/webrtc_pan_tilt_zoom_browsertest.cc b/chrome/browser/media/webrtc/webrtc_pan_tilt_zoom_browsertest.cc
index 49836f2b..0df8778 100644
--- a/chrome/browser/media/webrtc/webrtc_pan_tilt_zoom_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_pan_tilt_zoom_browsertest.cc
@@ -51,24 +51,25 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetUserMedia(%s);", GetParam().constraints),
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
 
   std::string microphone;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getMicrophonePermission();", &microphone));
+      tab->GetPrimaryMainFrame(), "getMicrophonePermission();", &microphone));
   EXPECT_EQ(microphone, GetParam().expected_microphone);
 
   std::string camera;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getCameraPermission();", &camera));
+      tab->GetPrimaryMainFrame(), "getCameraPermission();", &camera));
   EXPECT_EQ(camera, GetParam().expected_camera);
 
   std::string pan_tilt_zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, GetParam().expected_pan_tilt_zoom);
 }
 
@@ -235,33 +236,34 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetUserMedia(%s);", GetParam().constraints),
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
 
   std::string pan_tilt_zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, "granted");
 
   double pan;
   EXPECT_TRUE(content::ExecuteScriptAndExtractDouble(
-      tab->GetMainFrame(), "getTrackSetting('pan');", &pan));
+      tab->GetPrimaryMainFrame(), "getTrackSetting('pan');", &pan));
   EXPECT_EQ(pan, GetParam().expected_pan);
 
   double tilt;
   EXPECT_TRUE(content::ExecuteScriptAndExtractDouble(
-      tab->GetMainFrame(), "getTrackSetting('tilt');", &tilt));
+      tab->GetPrimaryMainFrame(), "getTrackSetting('tilt');", &tilt));
   EXPECT_EQ(tilt, GetParam().expected_tilt);
 
   double zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractDouble(
-      tab->GetMainFrame(), "getTrackSetting('zoom');", &zoom));
+      tab->GetPrimaryMainFrame(), "getTrackSetting('zoom');", &zoom));
   EXPECT_EQ(zoom, GetParam().expected_zoom);
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("checkConstraints(%s);",
                          GetParam().expected_constraints),
       &result));
@@ -340,28 +342,28 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetUserMedia({ video: { width: 640, %s: 101 } });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("checkConstraints({ width: 640, %s: 101 });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "checkConstraints-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("applyConstraints({ advanced: [{ %s: 102 }] });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "applyConstraints-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("checkConstraints({ advanced: [{ %s: 102 }] });",
                          Constraint()),
       &result));
@@ -375,28 +377,28 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetUserMedia({ video: { width: 640, %s: 101 } });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("checkConstraints({ width: 640, %s: 101 });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "checkConstraints-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       base::StringPrintf("runGetUserMedia({ video: { %s: true } });",
                          Constraint()),
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
 
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "checkConstraints({});", &result));
+      tab->GetPrimaryMainFrame(), "checkConstraints({});", &result));
   EXPECT_EQ(result, "checkConstraints-success");
 }
 
@@ -445,17 +447,18 @@
 
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "runRequestPanTiltZoom();", &result));
+      tab->GetPrimaryMainFrame(), "runRequestPanTiltZoom();", &result));
   EXPECT_EQ(result, "runRequestPanTiltZoom-success");
 
   std::string camera;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getCameraPermission();", &camera));
+      tab->GetPrimaryMainFrame(), "getCameraPermission();", &camera));
   EXPECT_EQ(camera, "granted");
 
   std::string pan_tilt_zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, IsPanTiltZoomSupported() ? "granted" : "prompt");
 }
 
@@ -499,19 +502,20 @@
                         /*zoom_supported=*/false);
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "runRequestPanTiltZoom();", &result));
+      tab->GetPrimaryMainFrame(), "runRequestPanTiltZoom();", &result));
   EXPECT_EQ(result, "runRequestPanTiltZoom-success");
 
   // Camera permission should be granted.
   std::string camera;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getCameraPermission();", &camera));
+      tab->GetPrimaryMainFrame(), "getCameraPermission();", &camera));
   EXPECT_EQ(camera, "granted");
 
   // Camera PTZ permission should not be granted.
   std::string pan_tilt_zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, "prompt");
 
   // Simulate camera device with PTZ support.
@@ -520,7 +524,8 @@
 
   // Camera PTZ permission should still not be granted.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, "prompt");
 }
 
@@ -534,19 +539,20 @@
                         /*zoom_supported=*/true);
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "runRequestPanTiltZoom();", &result));
+      tab->GetPrimaryMainFrame(), "runRequestPanTiltZoom();", &result));
   EXPECT_EQ(result, "runRequestPanTiltZoom-success");
 
   // Camera permission should be granted.
   std::string camera;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getCameraPermission();", &camera));
+      tab->GetPrimaryMainFrame(), "getCameraPermission();", &camera));
   EXPECT_EQ(camera, "granted");
 
   // Camera PTZ permission should be granted.
   std::string pan_tilt_zoom;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, "granted");
 
   // Simulate camera device with no PTZ support.
@@ -555,7 +561,8 @@
 
   // Camera PTZ permission should still be granted.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "getPanTiltZoomPermission();", &pan_tilt_zoom));
+      tab->GetPrimaryMainFrame(), "getPanTiltZoomPermission();",
+      &pan_tilt_zoom));
   EXPECT_EQ(pan_tilt_zoom, "granted");
 }
 
@@ -578,7 +585,7 @@
   // Access PTZ camera.
   std::string result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       "runGetUserMedia({ video: { pan: true, tilt: true, zoom: true } });",
       &result));
   EXPECT_EQ(result, "runGetUserMedia-success");
@@ -591,20 +598,20 @@
 
   // Pan can't be set when page is hidden.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ pan: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ pan: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-failure-SecurityError");
 
   // Tilt can't be set when page is hidden.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ tilt: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ tilt: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-failure-SecurityError");
 
   // Zoom can't be set when page is hidden.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ zoom: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ zoom: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-failure-SecurityError");
 
   // Show page.
@@ -615,19 +622,19 @@
 
   // Pan can be set when page is shown again.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ pan: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ pan: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-success");
 
   // Tilt can be set when page is shown again.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ tilt: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ tilt: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-success");
 
   // Zoom can be set when page is shown again.
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      tab->GetMainFrame(), "applyConstraints({ advanced: [{ zoom: 102 }] });",
-      &result));
+      tab->GetPrimaryMainFrame(),
+      "applyConstraints({ advanced: [{ zoom: 102 }] });", &result));
   EXPECT_EQ(result, "applyConstraints-success");
 }
diff --git a/chrome/browser/media/webrtc/webrtc_video_display_perf_browsertest.cc b/chrome/browser/media/webrtc/webrtc_video_display_perf_browsertest.cc
index e027535..7fdaa84f 100644
--- a/chrome/browser/media/webrtc/webrtc_video_display_perf_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_video_display_perf_browsertest.cc
@@ -233,7 +233,7 @@
         OpenPageAndGetUserMediaInNewTabWithConstraints(
             embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage),
             "{audio: true, video: false}");
-    const int process_id = right_tab->GetMainFrame()
+    const int process_id = right_tab->GetPrimaryMainFrame()
                                ->GetRenderViewHost()
                                ->GetProcess()
                                ->GetProcess()
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc
index 7517709..52d8711 100644
--- a/chrome/browser/media_galleries/media_file_system_registry.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry.cc
@@ -171,7 +171,7 @@
 
 void RPHReferenceManager::ReferenceFromWebContents(
     content::WebContents* contents) {
-  RenderProcessHost* rph = contents->GetMainFrame()->GetProcess();
+  RenderProcessHost* rph = contents->GetPrimaryMainFrame()->GetProcess();
   if (!base::Contains(observer_map_, rph)) {
     observer_map_[rph] = std::make_unique<RPHObserver>(this, rph);
   }
@@ -249,7 +249,7 @@
 
 void RPHReferenceManager::OnWebContentsDestroyedOrNavigated(
     WebContents* contents) {
-  RenderProcessHost* rph = contents->GetMainFrame()->GetProcess();
+  RenderProcessHost* rph = contents->GetPrimaryMainFrame()->GetProcess();
   auto rph_info = observer_map_.find(rph);
   DCHECK(rph_info != observer_map_.end());
 
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.cc b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.cc
index a037d76..65d6bd7 100644
--- a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.cc
+++ b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.cc
@@ -17,7 +17,8 @@
       content::WebContentsUserData<DesktopSessionDurationObserver>(
           *web_contents),
       service_(service) {
-  RegisterInputEventObserver(web_contents->GetMainFrame()->GetRenderViewHost());
+  RegisterInputEventObserver(
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost());
 }
 
 DesktopSessionDurationObserver::~DesktopSessionDurationObserver() {}
diff --git a/chrome/browser/metrics/first_web_contents_profiler.cc b/chrome/browser/metrics/first_web_contents_profiler.cc
index 623b9e6..867f658 100644
--- a/chrome/browser/metrics/first_web_contents_profiler.cc
+++ b/chrome/browser/metrics/first_web_contents_profiler.cc
@@ -73,7 +73,7 @@
 void FirstWebContentsProfiler::RecordFirstNonEmptyPaint() {
   startup_metric_utils::RecordFirstWebContentsNonEmptyPaint(
       base::TimeTicks::Now(),
-      web_contents()->GetMainFrame()->GetProcess()->GetLastInitTime());
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetLastInitTime());
 }
 
 bool FirstWebContentsProfiler::WasStartupInterrupted() {
diff --git a/chrome/browser/metrics/oom/out_of_memory_reporter.cc b/chrome/browser/metrics/oom/out_of_memory_reporter.cc
index ae751b9..3d77a3f 100644
--- a/chrome/browser/metrics/oom/out_of_memory_reporter.cc
+++ b/chrome/browser/metrics/oom/out_of_memory_reporter.cc
@@ -81,9 +81,9 @@
     return;
 
   // RenderProcessGone is only called for when the current RenderFrameHost of
-  // the primary main frame exits, so it is ok to call GetMainFrame here.
+  // the primary main frame exits, so it is ok to call GetPrimaryMainFrame here.
   crashed_render_process_id_ =
-      web_contents()->GetMainFrame()->GetProcess()->GetID();
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
 
 // On Android, we care about OOM protected crashes, which are obtained via
 // crash dump analysis. Otherwise we can use the termination status to
diff --git a/chrome/browser/metrics/tab_stats/tab_stats_tracker.cc b/chrome/browser/metrics/tab_stats/tab_stats_tracker.cc
index b02c3097..9d2c70b 100644
--- a/chrome/browser/metrics/tab_stats/tab_stats_tracker.cc
+++ b/chrome/browser/metrics/tab_stats/tab_stats_tracker.cc
@@ -292,7 +292,8 @@
                            TabStatsTracker* tab_stats_tracker)
       : content::WebContentsObserver(web_contents),
         tab_stats_tracker_(tab_stats_tracker),
-        ukm_source_id_(web_contents->GetMainFrame()->GetPageUkmSourceId()) {}
+        ukm_source_id_(
+            web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId()) {}
 
   WebContentsUsageObserver(const WebContentsUsageObserver&) = delete;
   WebContentsUsageObserver& operator=(const WebContentsUsageObserver&) = delete;
diff --git a/chrome/browser/metrics/tab_stats/tab_stats_tracker_browsertest.cc b/chrome/browser/metrics/tab_stats/tab_stats_tracker_browsertest.cc
index a652aca..ff06109 100644
--- a/chrome/browser/metrics/tab_stats/tab_stats_tracker_browsertest.cc
+++ b/chrome/browser/metrics/tab_stats/tab_stats_tracker_browsertest.cc
@@ -714,7 +714,7 @@
       .Times(0);
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_helper_.CreateFencedFrame(
-          GetWebContents()->GetMainFrame(),
+          GetWebContents()->GetPrimaryMainFrame(),
           embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   ASSERT_NE(nullptr, fenced_frame_host);
   ::testing::Mock::VerifyAndClear(&mock_observer);
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index f3336c2..827d90450 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -959,7 +959,7 @@
   EXPECT_NE(opener, sync_browser->tab_strip_model()->GetActiveWebContents());
   ukm::SourceId new_id = sync_browser->tab_strip_model()
                              ->GetActiveWebContents()
-                             ->GetMainFrame()
+                             ->GetPrimaryMainFrame()
                              ->GetPageUkmSourceId();
   ukm::UkmSource* new_tab_source = ukm_test_helper.GetSource(new_id);
   EXPECT_NE(nullptr, new_tab_source);
@@ -1006,7 +1006,7 @@
   EXPECT_NE(opener, sync_browser->tab_strip_model()->GetActiveWebContents());
   ukm::SourceId new_id = sync_browser->tab_strip_model()
                              ->GetActiveWebContents()
-                             ->GetMainFrame()
+                             ->GetPrimaryMainFrame()
                              ->GetPageUkmSourceId();
   ukm::UkmSource* new_tab_source = ukm_test_helper.GetSource(new_id);
   EXPECT_NE(nullptr, new_tab_source);
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
index 4b6c378..0794e4a 100644
--- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
+++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
@@ -18,7 +18,7 @@
 
 std::pair<ukm::SourceId, url::Origin> GetNavigationInfoForContents(
     content::WebContents* contents) {
-  auto* main_frame = contents->GetMainFrame();
+  auto* main_frame = contents->GetPrimaryMainFrame();
   if (!main_frame || main_frame->GetLastCommittedURL().is_empty())
     return std::make_pair(ukm::kInvalidSourceId, url::Origin());
 
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc
index a051b251..331a3da 100644
--- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc
+++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc
@@ -157,7 +157,7 @@
   EXPECT_EQ(browser()
                 ->tab_strip_model()
                 ->GetActiveWebContents()
-                ->GetMainFrame()
+                ->GetPrimaryMainFrame()
                 ->GetPageUkmSourceId(),
             interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
@@ -184,7 +184,7 @@
       interval_data.time_playing_video_full_screen_single_monitor.is_zero());
   EXPECT_TRUE(interval_data.time_with_open_webrtc_connection.is_zero());
   EXPECT_TRUE(interval_data.time_playing_video_in_visible_tab.is_zero());
-  EXPECT_EQ(contents1->GetMainFrame()->GetPageUkmSourceId(),
+  EXPECT_EQ(contents1->GetPrimaryMainFrame()->GetPageUkmSourceId(),
             interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval * 2,
             interval_data.source_id_for_longest_visible_origin_duration);
@@ -195,7 +195,7 @@
   auto expected_source_id = browser()
                                 ->tab_strip_model()
                                 ->GetActiveWebContents()
-                                ->GetMainFrame()
+                                ->GetPrimaryMainFrame()
                                 ->GetPageUkmSourceId();
   EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(
       0, TabStripModel::CLOSE_USER_GESTURE));
@@ -229,7 +229,7 @@
       interval_data.time_playing_video_full_screen_single_monitor.is_zero());
   EXPECT_TRUE(interval_data.time_with_open_webrtc_connection.is_zero());
   EXPECT_TRUE(interval_data.time_playing_video_in_visible_tab.is_zero());
-  EXPECT_EQ(contents1->GetMainFrame()->GetPageUkmSourceId(),
+  EXPECT_EQ(contents1->GetPrimaryMainFrame()->GetPageUkmSourceId(),
             interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
             interval_data.source_id_for_longest_visible_origin_duration);
@@ -244,7 +244,7 @@
   auto expected_source_id = browser()
                                 ->tab_strip_model()
                                 ->GetActiveWebContents()
-                                ->GetMainFrame()
+                                ->GetPrimaryMainFrame()
                                 ->GetPageUkmSourceId();
 
   auto interval_data = data_store_.ResetIntervalData();
@@ -292,7 +292,7 @@
   auto expected_source_id = browser()
                                 ->tab_strip_model()
                                 ->GetActiveWebContents()
-                                ->GetMainFrame()
+                                ->GetPrimaryMainFrame()
                                 ->GetPageUkmSourceId();
   EXPECT_EQ(2U, interval_data.max_tab_count);
   EXPECT_EQ(1U, interval_data.max_visible_window_count);
@@ -332,7 +332,7 @@
   expected_source_id = browser()
                            ->tab_strip_model()
                            ->GetWebContentsAt(1)
-                           ->GetMainFrame()
+                           ->GetPrimaryMainFrame()
                            ->GetPageUkmSourceId();
   tick_clock_.Advance(kInterval);
   interval_data = data_store_.ResetIntervalData();
@@ -359,7 +359,7 @@
   expected_source_id = browser()
                            ->tab_strip_model()
                            ->GetWebContentsAt(0)
-                           ->GetMainFrame()
+                           ->GetPrimaryMainFrame()
                            ->GetPageUkmSourceId();
   interval_data = data_store_.ResetIntervalData();
   EXPECT_EQ(2U, interval_data.max_tab_count);
@@ -406,7 +406,8 @@
   tick_clock_.Advance(kInterval);
   EXPECT_TRUE(content::ExecJs(contents, "exitFullscreen()"));
   waiter.Wait(false);
-  auto expected_source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  auto expected_source_id =
+      contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   auto interval_data = data_store_.ResetIntervalData();
   EXPECT_EQ(1U, interval_data.max_tab_count);
@@ -447,7 +448,8 @@
   EXPECT_TRUE(content::ExecJs(contents, "makeFullscreen('small_video')"));
   waiter.Wait(true);
   tick_clock_.Advance(kInterval * 2);
-  auto expected_source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  auto expected_source_id =
+      contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(
       1, TabStripModel::CLOSE_USER_GESTURE));
 
@@ -470,7 +472,7 @@
   expected_source_id = browser()
                            ->tab_strip_model()
                            ->GetActiveWebContents()
-                           ->GetMainFrame()
+                           ->GetPrimaryMainFrame()
                            ->GetPageUkmSourceId();
   EXPECT_EQ(1U, interval_data.max_tab_count);
   EXPECT_EQ(1U, interval_data.max_visible_window_count);
@@ -503,7 +505,8 @@
   EXPECT_TRUE(content::ExecJs(contents, "makeFullscreen('small_video')"));
   waiter.Wait(true);
   tick_clock_.Advance(kInterval);
-  auto expected_source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  auto expected_source_id =
+      contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   content::CrashTab(contents);
   tick_clock_.Advance(kInterval);
 
@@ -523,7 +526,7 @@
 
   EXPECT_TRUE(content::NavigateToURL(
       contents, embedded_test_server()->GetURL("/title2.html")));
-  expected_source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  expected_source_id = contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   tick_clock_.Advance(kInterval);
   interval_data = data_store_.ResetIntervalData();
   EXPECT_EQ(1U, interval_data.max_tab_count);
@@ -567,7 +570,7 @@
   EXPECT_EQ(browser()
                 ->tab_strip_model()
                 ->GetActiveWebContents()
-                ->GetMainFrame()
+                ->GetPrimaryMainFrame()
                 ->GetPageUkmSourceId(),
             interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_unittest.cc b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_unittest.cc
index 310c743..38ae552 100644
--- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_unittest.cc
+++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_unittest.cc
@@ -337,7 +337,7 @@
   EXPECT_EQ(content::Visibility::VISIBLE, contents1->GetVisibility());
   content::NavigationSimulator::NavigateAndCommitFromBrowser(contents1.get(),
                                                              GURL(kUrl1));
-  auto source_id_1 = contents1->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_1 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_NE(ukm::kInvalidSourceId, source_id_1);
 
   tab_usage_scenario_tracker_->OnTabAdded(contents1.get());
@@ -377,7 +377,7 @@
   // Make the tab visible and navigate to a different URL.
   MakeTabVisible(contents1.get());
   NavigateAndCommitTab(contents1.get(), kUrl2);
-  auto source_id_2 = contents1->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_2 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_NE(source_id_1, source_id_2);
   task_environment()->FastForwardBy(kInterval);
   interval_data = usage_scenario_data_store_.ResetIntervalData();
@@ -416,7 +416,7 @@
             usage_scenario_data_store_.GetVisibleSourceIdsForTesting().size());
 
   NavigateAndCommitTab(contents1.get(), kUrl1);
-  auto source_id_1 = contents1->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_1 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_NE(ukm::kInvalidSourceId, source_id_1);
 
   task_environment()->FastForwardBy(kInterval);
@@ -450,7 +450,7 @@
 
   task_environment()->FastForwardBy(kInterval);
   auto interval_data = usage_scenario_data_store_.ResetIntervalData();
-  auto source_id_1 = contents1->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_1 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_EQ(source_id_1, interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
             interval_data.source_id_for_longest_visible_origin_duration);
@@ -473,7 +473,7 @@
   MakeTabOccluded(contents1.get());
   task_environment()->FastForwardBy(kInterval);
   interval_data = usage_scenario_data_store_.ResetIntervalData();
-  auto source_id_2 = contents2->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_2 = contents2->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_EQ(source_id_2, interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
             interval_data.source_id_for_longest_visible_origin_duration);
@@ -485,7 +485,7 @@
   MakeTabVisible(contents3.get());
   task_environment()->FastForwardBy(kInterval);
   interval_data = usage_scenario_data_store_.ResetIntervalData();
-  auto source_id_3 = contents3->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_3 = contents3->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_EQ(source_id_3, interval_data.source_id_for_longest_visible_origin);
   EXPECT_EQ(kInterval,
             interval_data.source_id_for_longest_visible_origin_duration);
@@ -500,7 +500,7 @@
   EXPECT_EQ(content::Visibility::VISIBLE, contents1->GetVisibility());
   content::NavigationSimulator::NavigateAndCommitFromBrowser(contents1.get(),
                                                              GURL(kUrl1));
-  auto source_id_1 = contents1->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_1 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_NE(ukm::kInvalidSourceId, source_id_1);
   tab_usage_scenario_tracker_->OnTabAdded(contents1.get());
 
@@ -539,9 +539,9 @@
   NavigateAndCommitTab(contents2.get(), kUrl2);
   NavigateAndCommitTab(contents3.get(), kUrl3);
 
-  auto source_id_1 = contents1->GetMainFrame()->GetPageUkmSourceId();
-  auto source_id_2 = contents2->GetMainFrame()->GetPageUkmSourceId();
-  auto source_id_3 = contents3->GetMainFrame()->GetPageUkmSourceId();
+  auto source_id_1 = contents1->GetPrimaryMainFrame()->GetPageUkmSourceId();
+  auto source_id_2 = contents2->GetPrimaryMainFrame()->GetPageUkmSourceId();
+  auto source_id_3 = contents3->GetPrimaryMainFrame()->GetPageUkmSourceId();
   EXPECT_NE(source_id_1, source_id_2);
   EXPECT_NE(source_id_1, source_id_3);
   EXPECT_NE(source_id_2, source_id_3);
diff --git a/chrome/browser/mouse_events_interactive_uitest.cc b/chrome/browser/mouse_events_interactive_uitest.cc
index 2be5240..43df895 100644
--- a/chrome/browser/mouse_events_interactive_uitest.cc
+++ b/chrome/browser/mouse_events_interactive_uitest.cc
@@ -153,8 +153,8 @@
   menu_observer.WaitForMenuOpenAndClose();
 
   content::WebContents* tab = GetActiveWebContents();
-  tab->GetMainFrame()->ExecuteJavaScriptForTests(u"done()",
-                                                 base::NullCallback());
+  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"done()",
+                                                        base::NullCallback());
   const std::u16string success_title = u"without mouseleave";
   const std::u16string failure_title = u"with mouseleave";
   content::TitleWatcher done_title_watcher(tab, success_title);
@@ -181,15 +181,15 @@
   base::RunLoop dialog_wait;
   js_dialog_manager->SetDialogShownCallbackForTesting(
       dialog_wait.QuitClosure());
-  tab->GetMainFrame()->ExecuteJavaScriptForTests(u"alert()",
-                                                 base::NullCallback());
+  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
+                                                        base::NullCallback());
   dialog_wait.Run();
 
   // Cancel the dialog.
   js_dialog_manager->HandleJavaScriptDialog(tab, false, nullptr);
 
-  tab->GetMainFrame()->ExecuteJavaScriptForTests(u"done()",
-                                                 base::NullCallback());
+  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"done()",
+                                                        base::NullCallback());
   const std::u16string success_title = u"without mouseleave";
   const std::u16string failure_title = u"with mouseleave";
   content::TitleWatcher done_title_watcher(tab, success_title);
diff --git a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
index c305809..74a2f8b 100644
--- a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
+++ b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
@@ -132,7 +132,7 @@
   ukm::SourceId ukm_source_id = browser()
                                     ->tab_strip_model()
                                     ->GetActiveWebContents()
-                                    ->GetMainFrame()
+                                    ->GetPrimaryMainFrame()
                                     ->GetPageUkmSourceId();
 
   histogram_tester()->ExpectTotalCount(
@@ -247,7 +247,7 @@
   ukm::SourceId ukm_source_id = browser()
                                     ->tab_strip_model()
                                     ->GetActiveWebContents()
-                                    ->GetMainFrame()
+                                    ->GetPrimaryMainFrame()
                                     ->GetPageUkmSourceId();
 
   auto ukm_entries = test_ukm_recorder()->GetEntries(
@@ -318,7 +318,7 @@
   ukm::SourceId ukm_source_id = browser()
                                     ->tab_strip_model()
                                     ->GetActiveWebContents()
-                                    ->GetMainFrame()
+                                    ->GetPrimaryMainFrame()
                                     ->GetPageUkmSourceId();
 
   auto ukm_entries = test_ukm_recorder()->GetEntries(
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc
index e3a51ef4..33d71e6 100644
--- a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc
+++ b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc
@@ -752,7 +752,7 @@
   const GURL& fenced_frame_url =
       test_server()->GetURL("/fenced_frames/simple_page_with_anchors.html");
   std::ignore = fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(), fenced_frame_url);
+      web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
 
   // Make sure the fenced frame doesn't log any anchors.
   anchor_entries = test_ukm_recorder->GetEntriesByName(AnchorEntry::kEntryName);
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_keyed_service.cc b/chrome/browser/navigation_predictor/navigation_predictor_keyed_service.cc
index e54fdce..b617472 100644
--- a/chrome/browser/navigation_predictor/navigation_predictor_keyed_service.cc
+++ b/chrome/browser/navigation_predictor/navigation_predictor_keyed_service.cc
@@ -46,7 +46,7 @@
     return;
   }
 
-  prediction.web_contents()->GetMainFrame()->AddMessageToConsole(
+  prediction.web_contents()->GetPrimaryMainFrame()->AddMessageToConsole(
       blink::mojom::ConsoleMessageLevel::kInfo,
       "JSON Navigation Prediction: " + json_body);
 }
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc
index fbff366..5558cc6 100644
--- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc
+++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc
@@ -184,7 +184,7 @@
     return;
 
   url::Origin preconnect_origin =
-      web_contents()->GetMainFrame()->GetLastCommittedOrigin();
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   if (preconnect_origin.scheme() != url::kHttpScheme &&
       preconnect_origin.scheme() != url::kHttpsScheme) {
     return;
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc
index 6a05811..0eec9bc7 100644
--- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc
+++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc
@@ -551,7 +551,7 @@
       GetTestURL("/fenced_frames/anchors_different_area.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   // The count should not increase in DidFinishLoad method.
   histogram_tester.ExpectTotalCount("NavigationPredictor.IsPubliclyRoutable",
                                     1);
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc
index 4ad7dc8..c21bcee3 100644
--- a/chrome/browser/net/cookie_policy_browsertest.cc
+++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -147,7 +147,7 @@
   content::RenderFrameHost* GetFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return ChildFrameAt(web_contents->GetMainFrame(), 0);
+    return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   }
 
   content::RenderFrameHost* GetNestedFrame() {
diff --git a/chrome/browser/net/cookie_store_sameparty_browsertest.cc b/chrome/browser/net/cookie_store_sameparty_browsertest.cc
index 992e0d5..a0e6599 100644
--- a/chrome/browser/net/cookie_store_sameparty_browsertest.cc
+++ b/chrome/browser/net/cookie_store_sameparty_browsertest.cc
@@ -75,7 +75,7 @@
 
   content::RenderFrameHost* GetDescendantFrame(
       const std::vector<int>& indices) {
-    content::RenderFrameHost* frame = contents()->GetMainFrame();
+    content::RenderFrameHost* frame = contents()->GetPrimaryMainFrame();
     for (int index : indices) {
       frame = ChildFrameAt(frame, index);
     }
diff --git a/chrome/browser/net/cookie_store_samesite_browsertest.cc b/chrome/browser/net/cookie_store_samesite_browsertest.cc
index b02299e..8112def 100644
--- a/chrome/browser/net/cookie_store_samesite_browsertest.cc
+++ b/chrome/browser/net/cookie_store_samesite_browsertest.cc
@@ -69,7 +69,7 @@
   content::RenderFrameHost* GetFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return ChildFrameAt(web_contents->GetMainFrame(), 0);
+    return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   }
 
   std::string GetCookieSameSite(const std::string& cookie_name) {
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index 1b3844ac..26552b66 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -118,7 +118,8 @@
 
 [[nodiscard]] bool IsDisplayingText(Browser* browser, const std::string& text) {
   return IsDisplayingText(
-      browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), text);
+      browser->tab_strip_model()->GetActiveWebContents()->GetPrimaryMainFrame(),
+      text);
 }
 
 // Expands the more box on the currently displayed error page.
@@ -413,7 +414,7 @@
   // Can't use content::ExecuteScript because it waits for scripts to send
   // notification that they've run, and scripts that trigger a navigation may
   // not send that notification.
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.getElementById('reload-button').click();",
       base::NullCallback());
   nav_observer.Wait();
@@ -435,7 +436,7 @@
 
   // Do a same-document navigation on the error page, which should not result
   // in a new navigation.
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.location='#';", base::NullCallback());
   content::WaitForLoadStop(web_contents);
   // Page being displayed should not change.
@@ -446,7 +447,7 @@
   // Can't use content::ExecuteScript because it waits for scripts to send
   // notification that they've run, and scripts that trigger a navigation may
   // not send that notification.
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.getElementById('reload-button').click();",
       base::NullCallback());
   nav_observer2.Wait();
@@ -527,8 +528,8 @@
   {
     TestFailProvisionalLoadObserver fail_observer(wc);
     content::LoadStopObserver load_observer(wc);
-    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
-                                                  base::NullCallback());
+    wc->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+        base::ASCIIToUTF16(script), base::NullCallback());
     load_observer.Wait();
 
     // Ensure we saw the expected failure.
@@ -546,8 +547,8 @@
            "document.body.appendChild(frame);";
   {
     content::LoadStopObserver load_observer(wc);
-    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
-                                                  base::NullCallback());
+    wc->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+        base::ASCIIToUTF16(script), base::NullCallback());
     load_observer.Wait();
   }
 
@@ -556,8 +557,8 @@
   {
     TestFailProvisionalLoadObserver fail_observer(wc);
     content::LoadStopObserver load_observer(wc);
-    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
-                                                  base::NullCallback());
+    wc->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+        base::ASCIIToUTF16(script), base::NullCallback());
     load_observer.Wait();
 
     EXPECT_EQ(fail_url, fail_observer.fail_url());
@@ -756,7 +757,7 @@
   content::WebContents* web_contents =
     browser()->tab_strip_model()->GetActiveWebContents();
   content::TestNavigationObserver nav_observer(web_contents, 1);
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.getElementById('reload-button').click();",
       base::NullCallback());
   nav_observer.Wait();
@@ -787,7 +788,7 @@
 
   // Same-document navigation on an error page should not interrupt the
   // scheduled auto-reload which should still be pending on the WebContents.
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.location='#';", base::NullCallback());
 
   // Wait for the second auto reload to happen. It will succeed and update the
diff --git a/chrome/browser/net/net_error_tab_helper.cc b/chrome/browser/net/net_error_tab_helper.cc
index 7e6c023..fbf92b54 100644
--- a/chrome/browser/net/net_error_tab_helper.cc
+++ b/chrome/browser/net/net_error_tab_helper.cc
@@ -252,7 +252,7 @@
   DCHECK(dns_error_page_committed_);
 
   DVLOG(1) << "Sending status " << DnsProbeStatusToString(dns_probe_status_);
-  content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame();
 
   mojo::AssociatedRemote<chrome::mojom::NetworkDiagnosticsClient> client;
   rfh->GetRemoteAssociatedInterfaces()->GetInterface(&client);
@@ -280,7 +280,7 @@
     return;
 
   if (network_diagnostics_receivers_.GetCurrentTargetFrame() !=
-      web_contents()->GetMainFrame()) {
+      web_contents()->GetPrimaryMainFrame()) {
     return;
   }
 
diff --git a/chrome/browser/net/net_error_tab_helper_browsertest.cc b/chrome/browser/net/net_error_tab_helper_browsertest.cc
index c9efa7c..568dbb6 100644
--- a/chrome/browser/net/net_error_tab_helper_browsertest.cc
+++ b/chrome/browser/net/net_error_tab_helper_browsertest.cc
@@ -174,7 +174,7 @@
 
   // Overrides the last committed origin to treat the network error as the same
   // url with the non-opaque origins.
-  content::OverrideLastCommittedOrigin(GetWebContents()->GetMainFrame(),
+  content::OverrideLastCommittedOrigin(GetWebContents()->GetPrimaryMainFrame(),
                                        url::Origin::Create(initial_url));
 
   GURL prerender_url =
@@ -209,7 +209,7 @@
       const NetErrorTabHelperWithFencedFrameTest&) = delete;
 
   RenderFrameHost* primary_main_frame_host() {
-    return GetWebContents()->GetMainFrame();
+    return GetWebContents()->GetPrimaryMainFrame();
   }
 
   test::FencedFrameTestHelper& fenced_frame_test_helper() {
@@ -234,10 +234,11 @@
   GURL initial_url =
       net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
-  EvalJsResult result =
-      EvalJs(GetWebContents()->GetMainFrame(), kSearchingForDiagnosisScript);
+  EvalJsResult result = EvalJs(GetWebContents()->GetPrimaryMainFrame(),
+                               kSearchingForDiagnosisScript);
   ASSERT_TRUE(result.error.empty());
-  EXPECT_EQ(WebContentsCanShowDiagnosticsTool(GetWebContents()->GetMainFrame()),
+  EXPECT_EQ(WebContentsCanShowDiagnosticsTool(
+                GetWebContents()->GetPrimaryMainFrame()),
             result.ExtractString());
 }
 
@@ -247,7 +248,7 @@
       net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
   RenderFrameHost* inner_fenced_frame_rfh =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url,
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url,
           net::ERR_NAME_NOT_RESOLVED);
   EvalJsResult result =
       EvalJs(inner_fenced_frame_rfh, kSearchingForDiagnosisScript);
diff --git a/chrome/browser/net/net_error_tab_helper_unittest.cc b/chrome/browser/net/net_error_tab_helper_unittest.cc
index d529e9ff..b31931cf3 100644
--- a/chrome/browser/net/net_error_tab_helper_unittest.cc
+++ b/chrome/browser/net/net_error_tab_helper_unittest.cc
@@ -341,7 +341,7 @@
 // Makes sure that URLs are sanitized before running the platform network
 // diagnostics tool.
 TEST_F(NetErrorTabHelperTest, SanitizeDiagnosticsUrl) {
-  tab_helper()->SetCurrentTargetFrame(web_contents()->GetMainFrame());
+  tab_helper()->SetCurrentTargetFrame(web_contents()->GetPrimaryMainFrame());
   tab_helper()->network_diagnostics_interface()->RunNetworkDiagnostics(
       GURL("http://foo:bar@somewhere:123/hats?for#goats"));
   EXPECT_EQ("http://somewhere:123/",
@@ -362,7 +362,7 @@
   };
 
   for (const char* url : kUrls) {
-    tab_helper()->SetCurrentTargetFrame(web_contents()->GetMainFrame());
+    tab_helper()->SetCurrentTargetFrame(web_contents()->GetPrimaryMainFrame());
     tab_helper()->network_diagnostics_interface()
         ->RunNetworkDiagnostics(GURL(url));
     EXPECT_EQ(0, tab_helper()->times_diagnostics_dialog_invoked());
diff --git a/chrome/browser/net/private_network_access_browsertest.cc b/chrome/browser/net/private_network_access_browsertest.cc
index b8972cb6..3c13560 100644
--- a/chrome/browser/net/private_network_access_browsertest.cc
+++ b/chrome/browser/net/private_network_access_browsertest.cc
@@ -1295,8 +1295,9 @@
                        SpecialSchemeDevtools) {
   EXPECT_TRUE(content::NavigateToURL(
       web_contents(), GURL("devtools://devtools/bundled/devtools_app.html")));
-  EXPECT_TRUE(web_contents()->GetMainFrame()->GetLastCommittedURL().SchemeIs(
-      content::kChromeDevToolsScheme));
+  EXPECT_TRUE(
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL().SchemeIs(
+          content::kChromeDevToolsScheme));
 
   std::unique_ptr<net::EmbeddedTestServer> server = NewServer();
   GURL fetch_url = LocalNonSecureWithCrossOriginCors(*server);
@@ -1315,8 +1316,9 @@
                        SpecialSchemeChromeSearch) {
   EXPECT_TRUE(content::NavigateToURL(
       web_contents(), GURL("chrome-search://most-visited/title.html")));
-  ASSERT_TRUE(web_contents()->GetMainFrame()->GetLastCommittedURL().SchemeIs(
-      chrome::kChromeSearchScheme));
+  ASSERT_TRUE(
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL().SchemeIs(
+          chrome::kChromeSearchScheme));
 
   std::unique_ptr<net::EmbeddedTestServer> server = NewServer();
   GURL fetch_url = LocalNonSecureWithCrossOriginCors(*server);
@@ -1374,8 +1376,9 @@
   const GURL url = extension->GetResourceURL(kPageFile);
 
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
-  ASSERT_TRUE(web_contents()->GetMainFrame()->GetLastCommittedURL().SchemeIs(
-      extensions::kExtensionScheme));
+  ASSERT_TRUE(
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL().SchemeIs(
+          extensions::kExtensionScheme));
 
   std::unique_ptr<net::EmbeddedTestServer> server = NewServer();
   GURL fetch_url = LocalNonSecureWithCrossOriginCors(*server);
@@ -1419,8 +1422,9 @@
   dom_distiller::DistilledPageObserver(web_contents())
       .WaitUntilFinishedLoading();
 
-  EXPECT_TRUE(web_contents()->GetMainFrame()->GetLastCommittedURL().SchemeIs(
-      dom_distiller::kDomDistillerScheme));
+  EXPECT_TRUE(
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL().SchemeIs(
+          dom_distiller::kDomDistillerScheme));
 
   std::unique_ptr<net::EmbeddedTestServer> server = NewServer();
   GURL fetch_url = LocalNonSecureWithCrossOriginCors(*server);
diff --git a/chrome/browser/net/reporting_browsertest.cc b/chrome/browser/net/reporting_browsertest.cc
index 015038ba..dac0321 100644
--- a/chrome/browser/net/reporting_browsertest.cc
+++ b/chrome/browser/net/reporting_browsertest.cc
@@ -498,7 +498,8 @@
 
   // Simulate the page being killed due to being unresponsive.
   content::ScopedAllowRendererCrashes allow_renderer_crashes(contents);
-  contents->GetMainFrame()->GetProcess()->Shutdown(content::RESULT_CODE_HUNG);
+  contents->GetPrimaryMainFrame()->GetProcess()->Shutdown(
+      content::RESULT_CODE_HUNG);
 
   upload_response()->WaitForRequest();
   auto response = ParseReportUpload(upload_response()->http_request()->content);
diff --git a/chrome/browser/net/samesite_cookies_policy_browsertest.cc b/chrome/browser/net/samesite_cookies_policy_browsertest.cc
index 9a40ec10..4ad4658 100644
--- a/chrome/browser/net/samesite_cookies_policy_browsertest.cc
+++ b/chrome/browser/net/samesite_cookies_policy_browsertest.cc
@@ -76,13 +76,13 @@
   content::RenderFrameHost* GetChildFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return ChildFrameAt(web_contents->GetMainFrame(), 0);
+    return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   }
 
-  content::RenderFrameHost* GetMainFrame() {
+  content::RenderFrameHost* GetPrimaryMainFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   }
 
   void NavigateToHttpPageWithFrame(const std::string& host) {
@@ -306,9 +306,10 @@
   NavigateToHttpPageWithFrame("a.test");
 
   GURL secure_echo_url = GetURL("a.test", "/echoheader?cookie", true);
-  ASSERT_TRUE(NavigateToURLFromRenderer(GetMainFrame(), secure_echo_url));
+  ASSERT_TRUE(
+      NavigateToURLFromRenderer(GetPrimaryMainFrame(), secure_echo_url));
 
-  ExpectFrameContent(GetMainFrame(), "strictcookie=1");
+  ExpectFrameContent(GetPrimaryMainFrame(), "strictcookie=1");
 }
 
 IN_PROC_BROWSER_TEST_P(SameSiteCookiesPolicyTest,
@@ -324,9 +325,10 @@
   NavigateToHttpPageWithFrame("a.test");
 
   GURL secure_echo_url = GetURL("a.test", "/echoheader?cookie", true);
-  ASSERT_TRUE(NavigateToURLFromRenderer(GetMainFrame(), secure_echo_url));
+  ASSERT_TRUE(
+      NavigateToURLFromRenderer(GetPrimaryMainFrame(), secure_echo_url));
 
-  ExpectFrameContent(GetMainFrame(),
+  ExpectFrameContent(GetPrimaryMainFrame(),
                      IsSchemefulSameSiteEnabled() ? "None" : "strictcookie=1");
 }
 
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index a9e2b4ec..881c6d3e 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -124,8 +124,10 @@
       const GURL& url,
       mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
           handshake_client) {
-    content::RenderFrameHost* const frame =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* const frame = browser()
+                                                ->tab_strip_model()
+                                                ->GetActiveWebContents()
+                                                ->GetPrimaryMainFrame();
     content::RenderProcessHost* const process = frame->GetProcess();
 
     const std::vector<std::string> requested_protocols;
diff --git a/chrome/browser/notifications/notification_permission_browsertest.cc b/chrome/browser/notifications/notification_permission_browsertest.cc
index e522827..5603f2d3 100644
--- a/chrome/browser/notifications/notification_permission_browsertest.cc
+++ b/chrome/browser/notifications/notification_permission_browsertest.cc
@@ -156,13 +156,14 @@
   GrantNotificationPermissionForTest(TesterUrl());
 
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), TesterUrl()));
-  content::RenderFrameHost* main_frame = GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      GetActiveWebContents()->GetPrimaryMainFrame();
   EXPECT_EQ("granted", EvalJs(main_frame, "getNotificationPermission()"));
   EXPECT_EQ("granted",
             EvalJs(main_frame, "getServiceWorkerNotificationPermission()"));
 
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), EmbedderUrl()));
-  main_frame = GetActiveWebContents()->GetMainFrame();
+  main_frame = GetActiveWebContents()->GetPrimaryMainFrame();
   EXPECT_EQ("default", EvalJs(main_frame, "getNotificationPermission()"));
 
   content::RenderFrameHost* iframe = CreateChildIframe(main_frame, TesterUrl());
@@ -182,7 +183,8 @@
 
   // Verify that TesterUrl() has notification/push permission.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), TesterUrl()));
-  content::RenderFrameHost* main_frame = GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      GetActiveWebContents()->GetPrimaryMainFrame();
   EXPECT_EQ("granted", EvalJs(main_frame, "getNotificationPermission()"));
   EXPECT_EQ("granted",
             EvalJs(main_frame, "getServiceWorkerNotificationPermission()"));
@@ -195,7 +197,7 @@
   // Load a site that uses a dedicated StoragePartition and verify that it has
   // default notification/push permissions.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), IsolatedEmbedderUrl()));
-  main_frame = GetActiveWebContents()->GetMainFrame();
+  main_frame = GetActiveWebContents()->GetPrimaryMainFrame();
   EXPECT_EQ("default", EvalJs(main_frame, "getNotificationPermission()"));
   EXPECT_EQ("denied",
             EvalJs(main_frame, "getServiceWorkerNotificationPermission()"));
diff --git a/chrome/browser/notifications/notification_permission_context_unittest.cc b/chrome/browser/notifications/notification_permission_context_unittest.cc
index 21deb6a..99dd3711 100644
--- a/chrome/browser/notifications/notification_permission_context_unittest.cc
+++ b/chrome/browser/notifications/notification_permission_context_unittest.cc
@@ -274,8 +274,8 @@
 
   // Requesting permission for different origins should fail.
   permissions::PermissionRequestID request_id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ContentSetting result = CONTENT_SETTING_DEFAULT;
@@ -345,8 +345,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   base::TestMockTimeTaskRunner* task_runner = SwitchToMockTime();
@@ -413,12 +413,12 @@
   web_contents()->WasShown();
 
   const permissions::PermissionRequestID id1(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId(1));
   const permissions::PermissionRequestID id2(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId(2));
 
   base::TestMockTimeTaskRunner* task_runner = SwitchToMockTime();
diff --git a/chrome/browser/notifications/notification_ui_manager_interactive_uitest.cc b/chrome/browser/notifications/notification_ui_manager_interactive_uitest.cc
index c946c06..881cb50 100644
--- a/chrome/browser/notifications/notification_ui_manager_interactive_uitest.cc
+++ b/chrome/browser/notifications/notification_ui_manager_interactive_uitest.cc
@@ -72,7 +72,7 @@
   // will be returned, indicating whether the script was executed successfully.
   bool RunScript(const std::string& script, std::string* result) const {
     return content::ExecuteScriptAndExtractString(
-        GetActiveWebContents()->GetMainFrame(), script, result);
+        GetActiveWebContents()->GetPrimaryMainFrame(), script, result);
   }
 
   GURL TestPageUrl() const {
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
index 7d5968a..6a02ce5 100644
--- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
+++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -161,9 +161,11 @@
   // Executes |script| and stores the result as a string in |result|. A boolean
   // will be returned, indicating whether the script was executed successfully.
   bool RunScript(const std::string& script, std::string* result) const {
-    return content::ExecuteScriptAndExtractString(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        script, result);
+    return content::ExecuteScriptAndExtractString(browser()
+                                                      ->tab_strip_model()
+                                                      ->GetActiveWebContents()
+                                                      ->GetPrimaryMainFrame(),
+                                                  script, result);
   }
 
   GURL TestPageUrl() const {
diff --git a/chrome/browser/offline_pages/android/auto_fetch_page_load_watcher_unittest.cc b/chrome/browser/offline_pages/android/auto_fetch_page_load_watcher_unittest.cc
index 012940d..b100f66 100644
--- a/chrome/browser/offline_pages/android/auto_fetch_page_load_watcher_unittest.cc
+++ b/chrome/browser/offline_pages/android/auto_fetch_page_load_watcher_unittest.cc
@@ -332,7 +332,7 @@
   content::RenderFrameHostTester::For(main_rfh())
       ->InitializeRenderFrameIfNeeded();
   content::RenderFrameHost* fenced_frame_rfh =
-      CreateFencedFrame(web_content->GetMainFrame());
+      CreateFencedFrame(web_content->GetPrimaryMainFrame());
   GURL kFencedFrameUrl("http://fencedframe.com");
   std::unique_ptr<content::NavigationSimulator> navigation_simulator =
       content::NavigationSimulator::CreateRendererInitiated(kFencedFrameUrl,
diff --git a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
index 5e706e2..1008e584 100644
--- a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
+++ b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
@@ -259,7 +259,8 @@
 content::WebContents::Getter GetWebContentsGetter(
     content::WebContents* web_contents) {
   // The FrameTreeNode ID should be used to access the WebContents.
-  int frame_tree_node_id = web_contents->GetMainFrame()->GetFrameTreeNodeId();
+  int frame_tree_node_id =
+      web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId();
   if (frame_tree_node_id != content::RenderFrameHost::kNoFrameTreeNodeId) {
     return base::BindRepeating(content::WebContents::FromFrameTreeNodeId,
                                frame_tree_node_id);
@@ -269,8 +270,8 @@
   // the WebContents.
   return base::BindRepeating(
       &GetWebContentsByFrameID,
-      web_contents->GetMainFrame()->GetProcess()->GetID(),
-      web_contents->GetMainFrame()->GetRoutingID());
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents->GetPrimaryMainFrame()->GetRoutingID());
 }
 
 void DownloadAsFile(content::WebContents* web_contents, const GURL& url) {
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
index 9122d22..ed2ba675 100644
--- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
+++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -640,7 +640,7 @@
   // Create handle with net error code.
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   handle.set_is_error_page(true);
   handle.set_net_error_code(net::Error::ERR_NAME_NOT_RESOLVED);
@@ -674,7 +674,7 @@
 
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   offliner()->DidFinishNavigation(&handle);
 
@@ -705,7 +705,7 @@
 
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   offliner()->DidFinishNavigation(&handle);
 
@@ -736,7 +736,7 @@
 
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   offliner()->DidFinishNavigation(&handle);
 
@@ -763,7 +763,7 @@
       std::move(visible_security_state));
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   offliner()->DidFinishNavigation(&handle);
 
@@ -785,7 +785,7 @@
   // Create handle with net error code.
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   handle.set_is_error_page(true);
   handle.set_net_error_code(net::Error::ERR_INTERNET_DISCONNECTED);
@@ -808,7 +808,7 @@
 
   // Called after calling LoadAndSave so we have web_contents to work with.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   offliner()->DidFinishNavigation(&handle);
 }
@@ -932,7 +932,7 @@
   // Simulate that DidFinishNavigation method is called with an error in a
   // non-primary mainframe.
   content::MockNavigationHandle handle(
-      GURL(kHttpUrl), offliner()->web_contents()->GetMainFrame());
+      GURL(kHttpUrl), offliner()->web_contents()->GetPrimaryMainFrame());
   handle.set_has_committed(true);
   handle.set_is_error_page(true);
   handle.set_net_error_code(net::Error::ERR_NAME_NOT_RESOLVED);
diff --git a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
index 1c8bcf04..76920f1 100644
--- a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
@@ -974,7 +974,8 @@
 
   url_loader_ = OfflinePageURLLoader::Create(
       navigation_ui_data_.get(),
-      test_->web_contents()->GetMainFrame()->GetFrameTreeNodeId(), request,
+      test_->web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
+      request,
       base::BindOnce(&OfflinePageURLLoaderBuilder::MaybeStartLoader,
                      base::Unretained(this), request));
 
diff --git a/chrome/browser/offline_pages/offline_page_tab_helper.cc b/chrome/browser/offline_pages/offline_page_tab_helper.cc
index c171682..dd37900 100644
--- a/chrome/browser/offline_pages/offline_page_tab_helper.cc
+++ b/chrome/browser/offline_pages/offline_page_tab_helper.cc
@@ -131,7 +131,7 @@
     const GURL& main_frame_url,
     base::Time date) {
   if (mhtml_page_notifier_receivers_.GetCurrentTargetFrame() !=
-      web_contents()->GetMainFrame()) {
+      web_contents()->GetPrimaryMainFrame()) {
     return;
   }
 
diff --git a/chrome/browser/offline_pages/offline_page_tab_helper_unittest.cc b/chrome/browser/offline_pages/offline_page_tab_helper_unittest.cc
index c9279d3..7577e346 100644
--- a/chrome/browser/offline_pages/offline_page_tab_helper_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_tab_helper_unittest.cc
@@ -149,7 +149,8 @@
     const GURL& mhtml_url,
     base::Time mhtml_creation_time,
     MHTMLLoadResult load_result) {
-  tab_helper()->SetCurrentTargetFrameForTest(web_contents()->GetMainFrame());
+  tab_helper()->SetCurrentTargetFrameForTest(
+      web_contents()->GetPrimaryMainFrame());
 
   // Simulate navigation
   CreateNavigationSimulator(GURL("file://foo"));
@@ -397,7 +398,8 @@
   GURL mhtml_url("https://www.example.com");
   base::HistogramTester histogram_tester;
 
-  tab_helper()->SetCurrentTargetFrameForTest(web_contents()->GetMainFrame());
+  tab_helper()->SetCurrentTargetFrameForTest(
+      web_contents()->GetPrimaryMainFrame());
 
   // Simulate navigation
   CreateNavigationSimulator(GURL("file://foo"));
@@ -442,8 +444,8 @@
   SimulateOfflinePageLoad(kTestUrl, kTestMhtmlCreationTime,
                           MHTMLLoadResult::kSuccess);
 
-  int process_id = web_contents()->GetMainFrame()->GetProcess()->GetID();
-  int main_frame_id = web_contents()->GetMainFrame()->GetRoutingID();
+  int process_id = web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+  int main_frame_id = web_contents()->GetPrimaryMainFrame()->GetRoutingID();
 
   // Navigate away.
   content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(),
diff --git a/chrome/browser/offline_pages/offline_page_utils.cc b/chrome/browser/offline_pages/offline_page_utils.cc
index 288ffbe..7e8536c 100644
--- a/chrome/browser/offline_pages/offline_page_utils.cc
+++ b/chrome/browser/offline_pages/offline_page_utils.cc
@@ -130,7 +130,8 @@
 content::WebContents::Getter GetWebContentsGetter(
     content::WebContents* web_contents) {
   // The FrameTreeNode ID should be used to access the WebContents.
-  int frame_tree_node_id = web_contents->GetMainFrame()->GetFrameTreeNodeId();
+  int frame_tree_node_id =
+      web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId();
   if (frame_tree_node_id != content::RenderFrameHost::kNoFrameTreeNodeId) {
     return base::BindRepeating(content::WebContents::FromFrameTreeNodeId,
                                frame_tree_node_id);
@@ -140,8 +141,8 @@
   // the WebContents.
   return base::BindRepeating(
       &GetWebContentsByFrameID,
-      web_contents->GetMainFrame()->GetProcess()->GetID(),
-      web_contents->GetMainFrame()->GetRoutingID());
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents->GetPrimaryMainFrame()->GetRoutingID());
 }
 
 void AcquireFileAccessPermissionDoneForScheduleDownload(
diff --git a/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc b/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc
index 7241d56..94b1724 100644
--- a/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc
+++ b/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc
@@ -143,7 +143,7 @@
 void OptimizationGuideWebContentsObserver::PostFetchHintsUsingManager() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!web_contents()
-           ->GetMainFrame()
+           ->GetPrimaryMainFrame()
            ->GetLastCommittedURL()
            .SchemeIsHTTPOrHTTPS())
     return;
diff --git a/chrome/browser/optimization_guide/page_text_observer_browsertest.cc b/chrome/browser/optimization_guide/page_text_observer_browsertest.cc
index be39c06b..908b8dff 100644
--- a/chrome/browser/optimization_guide/page_text_observer_browsertest.cc
+++ b/chrome/browser/optimization_guide/page_text_observer_browsertest.cc
@@ -204,7 +204,7 @@
       ::testing::UnorderedElementsAreArray({
           MakeFrameDump(
               mojom::TextDumpEvent::kFirstLayout,
-              web_contents()->GetMainFrame()->GetGlobalId(),
+              web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
               /*amp_frame=*/false,
               web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
               u"hello"),
@@ -260,7 +260,8 @@
       SCOPED_TRACE(result);
 
       // These fields are the same for both events.
-      EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(), result.rfh_id());
+      EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
+                result.rfh_id());
       EXPECT_FALSE(result.amp_frame());
       EXPECT_EQ(
           web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
@@ -348,7 +349,8 @@
       has_amp_result = true;
     } else {
       EXPECT_EQ(mojom::TextDumpEvent::kFirstLayout, result.event());
-      EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(), result.rfh_id());
+      EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
+                result.rfh_id());
       EXPECT_EQ(
           web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
           result.unique_navigation_id());
@@ -393,7 +395,8 @@
   const auto& result = *consumer.result()->frame_results().begin();
 
   EXPECT_EQ(mojom::TextDumpEvent::kFirstLayout, result.event());
-  EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(), result.rfh_id());
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
+            result.rfh_id());
   EXPECT_FALSE(result.amp_frame());
   EXPECT_EQ(web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
             result.unique_navigation_id());
@@ -447,7 +450,7 @@
       ::testing::UnorderedElementsAreArray({
           MakeFrameDump(
               mojom::TextDumpEvent::kFinishedLoad,
-              web_contents()->GetMainFrame()->GetGlobalId(),
+              web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
               /*amp_frame=*/false,
               web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
               u"mainframe\n\nhello"),
@@ -485,7 +488,7 @@
       ::testing::UnorderedElementsAreArray({
           MakeFrameDump(
               mojom::TextDumpEvent::kFirstLayout,
-              web_contents()->GetMainFrame()->GetGlobalId(),
+              web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
               /*amp_frame=*/false,
               web_contents()->GetController().GetVisibleEntry()->GetUniqueID(),
               u"mainframe"),
@@ -529,7 +532,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   // Loading a URL in a fenced frame should not increase
diff --git a/chrome/browser/page_info/about_this_site_controller_android.cc b/chrome/browser/page_info/about_this_site_controller_android.cc
index b518a42..a45abc51c 100644
--- a/chrome/browser/page_info/about_this_site_controller_android.cc
+++ b/chrome/browser/page_info/about_this_site_controller_android.cc
@@ -37,7 +37,7 @@
     return nullptr;
   auto url = url::GURLAndroid::ToNativeGURL(env, j_url);
   auto source_id = content::WebContents::FromJavaWebContents(j_webContents)
-                       ->GetMainFrame()
+                       ->GetPrimaryMainFrame()
                        ->GetPageUkmSourceId();
   auto info = service->GetAboutThisSiteInfo(*url, source_id);
   if (!info)
diff --git a/chrome/browser/page_info/about_this_site_tab_helper.cc b/chrome/browser/page_info/about_this_site_tab_helper.cc
index 0e9fc34..f6a451a 100644
--- a/chrome/browser/page_info/about_this_site_tab_helper.cc
+++ b/chrome/browser/page_info/about_this_site_tab_helper.cc
@@ -149,7 +149,7 @@
 void AboutThisSiteTabHelper::ShowBanner(
     page_info::proto::BannerInfo banner_info) {
   ukm::SourceId source_id =
-      web_contents()->GetMainFrame()->GetPageUkmSourceId();
+      web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
   GURL url = web_contents()->GetLastCommittedURL();
   base::OnceClosure on_dimiss =
       base::BindOnce(&page_info::AboutThisSiteService::OnBannerDismissed,
diff --git a/chrome/browser/page_load_metrics/integration_tests/event_counts_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/event_counts_browsertest.cc
index 35b2b97..319a246e 100644
--- a/chrome/browser/page_load_metrics/integration_tests/event_counts_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/event_counts_browsertest.cc
@@ -62,7 +62,7 @@
 
   // We should wait for the main frame's hit-test data to be ready before
   // sending the click event below to avoid flakiness.
-  content::WaitForHitTestData(web_contents()->GetMainFrame());
+  content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
   // Ensure the compositor thread is aware of the event listener.
   content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost());
   frame_observer.Wait();
@@ -139,7 +139,7 @@
 
   // We should wait for the main frame's hit-test data to be ready before
   // sending the touch events below to avoid flakiness.
-  content::WaitForHitTestData(web_contents()->GetMainFrame());
+  content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
   // Ensure the compositor thread is aware of the event listener.
   content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost());
   frame_observer.Wait();
diff --git a/chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc
index ec1710f..b6a766d 100644
--- a/chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc
@@ -46,7 +46,7 @@
 
   // We should wait for the main frame's hit-test data to be ready before
   // sending the click event below to avoid flakiness.
-  content::WaitForHitTestData(web_contents()->GetMainFrame());
+  content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
   // Ensure the compositor thread is ready for mouse events.
   content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost());
   frame_observer.Wait();
diff --git a/chrome/browser/page_load_metrics/integration_tests/first_scroll_delay_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/first_scroll_delay_browsertest.cc
index c7ce649..bc5a1733 100644
--- a/chrome/browser/page_load_metrics/integration_tests/first_scroll_delay_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/first_scroll_delay_browsertest.cc
@@ -31,7 +31,7 @@
 
   // We should wait for the main frame's hit-test data to be ready before
   // sending the click event below to avoid flakiness.
-  content::WaitForHitTestData(web_contents()->GetMainFrame());
+  content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
   // Ensure the compositor thread is ready for wheel events.
   content::MainThreadFrameObserver main_thread(GetRenderWidgetHost());
   main_thread.Wait();
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index 6d88e345..2b9fda2 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -167,7 +167,7 @@
                        LargestContentfulPaint_SubframeInput) {
   Start();
   Load("/lcp_subframe_input.html");
-  auto* sub = ChildFrameAt(web_contents()->GetMainFrame(), 0);
+  auto* sub = ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(EvalJs(sub, "test_step_1()").value.GetString(), "green-16x16.png");
 
   content::SimulateMouseClickAt(web_contents(), 0,
@@ -204,7 +204,7 @@
 
   base::RunLoop run_loop;
   client->CapturePaintPreview(
-      params, web_contents()->GetMainFrame(),
+      params, web_contents()->GetPrimaryMainFrame(),
       base::BindOnce(
           [](base::OnceClosure callback, base::UnguessableToken,
              paint_preview::mojom::PaintPreviewStatus,
@@ -275,7 +275,8 @@
     waiter->AddMinimumCompleteResourcesExpectation(entries);
     Start();
     Load(html_name);
-    EXPECT_EQ(EvalJs(web_contents()->GetMainFrame(), "run_test()").error, "");
+    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(), "run_test()").error,
+              "");
 
     // Need to navigate away from the test html page to force metrics to get
     // flushed/synced.
@@ -327,11 +328,12 @@
     waiter->AddMinimumCompleteResourcesExpectation(2);
     Start();
     Load(html_name);
-    EXPECT_EQ(EvalJs(web_contents()->GetMainFrame(), "run_test(1)").error, "");
+    EXPECT_EQ(
+        EvalJs(web_contents()->GetPrimaryMainFrame(), "run_test(1)").error, "");
 
     // We should wait for the main frame's hit-test data to be ready before
     // sending the mouse events below to avoid flakiness.
-    content::WaitForHitTestData(web_contents()->GetMainFrame());
+    content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
     // Ensure the compositor thread is aware of the mouse events.
     content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost());
     frame_observer.Wait();
@@ -345,7 +347,7 @@
                    ", y: " + base::NumberToString(y1) + " }, ] }], ()=>{});"));
 
     // Wait for a second image to load and for LCP entry to be there.
-    EXPECT_EQ(EvalJs(web_contents()->GetMainFrame(),
+    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
                      "run_test(/*entries_expected= */" + entries + ")")
                   .error,
               "");
@@ -359,12 +361,13 @@
       // currently a second mouse move call is not dispatching the event as it
       // should. So instead, we dispatch the event directly.
       EXPECT_EQ(
-          EvalJs(web_contents()->GetMainFrame(), "dispatch_mouseover()").error,
+          EvalJs(web_contents()->GetPrimaryMainFrame(), "dispatch_mouseover()")
+              .error,
           "");
 
       // Wait for a third image (potentially) to load and for LCP entry to be
       // there.
-      EXPECT_EQ(EvalJs(web_contents()->GetMainFrame(),
+      EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
                        "run_test(/*entries_expected= */" + entries2 + ")")
                     .error,
                 "");
diff --git a/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
index b05ca54..e54da21 100644
--- a/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
@@ -105,7 +105,7 @@
 
   // We should wait for the main frame's hit-test data to be ready before
   // sending the click event below to avoid flakiness.
-  content::WaitForHitTestData(web_contents()->GetMainFrame());
+  content::WaitForHitTestData(web_contents()->GetPrimaryMainFrame());
   // Ensure the compositor thread is aware of the mouse events.
   content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost());
   frame_observer.Wait();
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_android_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_android_browsertest.cc
index 7c0bd22..e4983f0 100644
--- a/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_android_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_android_browsertest.cc
@@ -101,7 +101,8 @@
 
   // blank_with_adiframe_writer loads a script tagged as an ad, verify it is not
   // loaded and the subresource filter UI for ad blocking is shown.
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
   EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents)
                 ->infobar_count(),
             1u);
@@ -155,7 +156,8 @@
   // blank_with_adiframe_writer loads a script tagged as an ad, verify it is
   // loaded as ads are not blocked and the subresource filter UI is not
   // shown.
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
 
   // No ads blocked infobar should be shown as we have not triggered the
   // intervention.
@@ -230,7 +232,8 @@
 
   // blank_with_adiframe_writer loads a script tagged as an ad, verify it is not
   // loaded and the subresource filter UI for ad blocking is shown.
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
 
   EXPECT_EQ(messages_test_helper.GetMessageCount(
                 web_contents->GetTopLevelNativeWindow()),
@@ -284,7 +287,8 @@
   // blank_with_adiframe_writer loads a script tagged as an ad, verify it is
   // loaded as ads are not blocked and the subresource filter UI is not
   // shown.
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
 
   // No ads blocked message should be shown as we have not triggered the
   // intervention.
@@ -357,7 +361,8 @@
 
   // We are not enforcing ad blocking on ads violations, site should load
   // as expected without subresource filter UI.
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
 
   // No ads blocked prompt should be shown as we have not triggered the
   // intervention.
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_browsertest.cc
index e66bd65b..f7aab172 100644
--- a/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_browsertest.cc
@@ -123,7 +123,8 @@
 
   // We are not enforcing ad blocking on ads violations, site should load
   // as expected without subresource filter UI.
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
   // No ads blocked infobar should be shown as we have not triggered the
   // intervention.
   histogram_tester.ExpectBucketCount(
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
index 7f72c48..cd67f46 100644
--- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -893,7 +893,7 @@
 
   // Activate one frame by executing a dummy script.
   content::RenderFrameHost* ad_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   const std::string no_op_script = "// No-op script";
   EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));
 
@@ -946,13 +946,13 @@
   // activate the second frame due to same-origin visibility user activation.
   // The activation of the second frame by this heuristic should be ignored.
   content::RenderFrameHost* ad_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   const std::string no_op_script = "// No-op script";
   EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));
 
   // Activate the other frame directly by executing a dummy script.
   content::RenderFrameHost* ad_frame_2 =
-      ChildFrameAt(web_contents->GetMainFrame(), 1);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 1);
   EXPECT_TRUE(ExecuteScript(ad_frame_2, no_op_script));
 
   // Ensure both frames are marked active.
@@ -1325,7 +1325,7 @@
 
   // Wait for the video to autoplay in the frame.
   content::RenderFrameHost* ad_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   const std::string play_script =
       "var video = document.getElementsByTagName('video')[0];"
       "video.onplaying = () => { "
@@ -1545,7 +1545,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(
                      "foo.com", "/ad_tagging/frame_factory.html")));
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"createAdFrame('frame_factory.html', '');", base::NullCallback());
   // Two pages subresources should have been reported as ad. The iframe resource
   // and its three subresources should also be reported as ads.
@@ -1565,7 +1565,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(
                      "foo.com", "/ad_tagging/frame_factory.html")));
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"createAdFrame('frame_factory.html', 'test');", base::NullCallback());
   waiter->AddMinimumAdResourceExpectation(6);
   waiter->Wait();
@@ -1748,7 +1748,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
   content::RenderFrameHost* ad_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   content::DOMMessageQueue message_queue(ad_frame);
 
@@ -1831,7 +1831,7 @@
   child_observer.Wait();
 
   content::RenderFrameHost* ad_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   auto cross_origin_ad_url = embedded_test_server()->GetURL(
       "xyz.com", "/ad_tagging/frame_factory.html");
@@ -2140,7 +2140,7 @@
   GURL url = embedded_test_server()->GetURL("foo.com",
                                             "/ad_tagging/frame_factory.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"createAdFrame('multiple_mimes.html', 'test');", base::NullCallback());
   waiter->AddMinimumAdResourceExpectation(8);
   waiter->Wait();
@@ -2447,14 +2447,15 @@
                        content::GlobalRenderFrameHostIdHasher>
         frame_routing_ids;
 
-    web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-        [](std::unordered_set<content::GlobalRenderFrameHostId,
-                              content::GlobalRenderFrameHostIdHasher>*
-               frame_routing_ids,
-           content::RenderFrameHost* frame) {
-          frame_routing_ids->insert(frame->GetGlobalId());
-        },
-        &frame_routing_ids));
+    web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+        base::BindRepeating(
+            [](std::unordered_set<content::GlobalRenderFrameHostId,
+                                  content::GlobalRenderFrameHostIdHasher>*
+                   frame_routing_ids,
+               content::RenderFrameHost* frame) {
+              frame_routing_ids->insert(frame->GetGlobalId());
+            },
+            &frame_routing_ids));
 
     return frame_routing_ids;
   }
@@ -2494,7 +2495,7 @@
   waiter->AddMemoryUpdateExpectation(browser()
                                          ->tab_strip_model()
                                          ->GetActiveWebContents()
-                                         ->GetMainFrame()
+                                         ->GetPrimaryMainFrame()
                                          ->GetGlobalId());
 
   // Navigate to the main URL.
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/large_sticky_ad_intervention_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/large_sticky_ad_intervention_browsertest.cc
index c59b61cd..a0f03c47 100644
--- a/chrome/browser/page_load_metrics/observers/ad_metrics/large_sticky_ad_intervention_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ad_metrics/large_sticky_ad_intervention_browsertest.cc
@@ -67,7 +67,8 @@
   // ad script is loaded and that the subresource filter UI doesn't show up.
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
@@ -93,7 +94,8 @@
   // shows up.
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
 
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 1);
@@ -139,7 +141,8 @@
   // running in dry run mode.
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/overlay_popup_ad_intervention_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/overlay_popup_ad_intervention_browsertest.cc
index 3c64362..bacb43be 100644
--- a/chrome/browser/page_load_metrics/observers/ad_metrics/overlay_popup_ad_intervention_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ad_metrics/overlay_popup_ad_intervention_browsertest.cc
@@ -77,7 +77,8 @@
   // ad script is loaded and that the subresource filter UI doesn't show up.
   EXPECT_TRUE(content::NavigateToURL(web_contents, url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
@@ -105,7 +106,8 @@
   // shows up.
   EXPECT_TRUE(content::NavigateToURL(web_contents, url));
 
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 1);
@@ -153,7 +155,8 @@
   // running in dry run mode.
   EXPECT_TRUE(content::NavigateToURL(web_contents, url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       "SubresourceFilter.Actions2",
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
diff --git a/chrome/browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc
index 4746569..6db2113d 100644
--- a/chrome/browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc
@@ -188,7 +188,8 @@
   SetNetworkQualityMock();
   auto navigation_simulator =
       content::NavigationSimulator::CreateRendererInitiated(
-          GURL("https://www.example.com"), web_contents()->GetMainFrame());
+          GURL("https://www.example.com"),
+          web_contents()->GetPrimaryMainFrame());
   navigation_simulator->Start();
   int frame_tree_node_id =
       navigation_simulator->GetNavigationHandle()->GetFrameTreeNodeId();
diff --git a/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
index 5060140..b1942f9 100644
--- a/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
@@ -47,7 +47,7 @@
 
  protected:
   content::RenderFrameHost* top_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter>
diff --git a/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_browsertest.cc
index ee8023e2..1220b2c 100644
--- a/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_browsertest.cc
@@ -169,7 +169,7 @@
       https_test_server()->GetURL("/page_load_metrics/amp_basic.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), kFencedFrameUrl);
+          GetWebContents()->GetPrimaryMainFrame(), kFencedFrameUrl);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   waiter.Wait();
diff --git a/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_unittest.cc
index 92737c16..2d1726cf 100644
--- a/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_unittest.cc
@@ -228,7 +228,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -288,7 +288,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh())
       ->CommitSameDocument();
@@ -341,7 +341,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -420,7 +420,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -466,7 +466,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -534,7 +534,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -618,7 +618,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -704,7 +704,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -773,7 +773,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -830,7 +830,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -882,7 +882,7 @@
       "https://ampsubframe.com/page2"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage2");
   content::RenderFrameHost* subframe2 = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe2", subframe_url2);
+      web_contents()->GetPrimaryMainFrame(), "subframe2", subframe_url2);
 
   // Perform a main-frame navigation to a different AMP document (not the
   // prerender).
@@ -894,7 +894,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe1 = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe1", subframe_url1);
+      web_contents()->GetPrimaryMainFrame(), "subframe1", subframe_url1);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -998,7 +998,7 @@
       "https://ampsubframe.com/page"
       "?amp_js_v=0.1#viewerUrl=https%3A%2F%2Fampviewer.com%2Fpage");
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
@@ -1043,7 +1043,7 @@
 
   // Create a non-AMP subframe document.
   GURL subframe_url("https://example.com/");
-  AppendChildFrameAndNavigateAndCommit(web_contents()->GetMainFrame(),
+  AppendChildFrameAndNavigateAndCommit(web_contents()->GetPrimaryMainFrame(),
                                        "subframe", subframe_url);
 
   // Navigate the main frame to trigger metrics recording.
@@ -1079,7 +1079,7 @@
       ->CommitSameDocument();
 
   content::RenderFrameHost* subframe = AppendChildFrameAndNavigateAndCommit(
-      web_contents()->GetMainFrame(), "subframe", subframe_url);
+      web_contents()->GetPrimaryMainFrame(), "subframe", subframe_url);
 
   page_load_metrics::mojom::FrameMetadata metadata;
   metadata.behavior_flags =
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
index 5a77218b..391d473 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -332,7 +332,7 @@
                                        .GetLastCommittedEntry()
                                        ->GetMainFrameDocumentSequenceNumber();
 
-  render_process_assignment_ = web_contents->GetMainFrame()
+  render_process_assignment_ = web_contents->GetPrimaryMainFrame()
                                    ->GetSiteInstance()
                                    ->GetLastProcessAssignmentOutcome();
 
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
index 79ac821..86d1fa82 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
@@ -522,7 +522,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -580,7 +580,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -988,7 +988,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -1040,7 +1040,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -1075,7 +1075,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -1130,12 +1130,12 @@
   RenderFrameHost* same_site_subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSameSiteSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("same_site_subframe"));
   RenderFrameHost* cross_site_subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kCrossSiteSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("cross_site_subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -1191,7 +1191,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate timing updates in the main frame and the subframe.
@@ -2043,7 +2043,7 @@
   RenderFrameHost* subframe =
       NavigationSimulator::NavigateAndCommitFromDocument(
           GURL(kSubframeTestUrl),
-          RenderFrameHostTester::For(web_contents()->GetMainFrame())
+          RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
               ->AppendChild("subframe"));
 
   // Simulate layout instability in the subframe.
@@ -2676,7 +2676,7 @@
 RenderFrameHost* CLSUkmPageLoadMetricsObserverTest::NavigateSubframe() {
   return NavigationSimulator::NavigateAndCommitFromDocument(
       GURL(kSubframeTestUrl),
-      RenderFrameHostTester::For(web_contents()->GetMainFrame())
+      RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
           ->AppendChild("subframe"));
 }
 
@@ -2715,7 +2715,7 @@
     bool input_in_subframe) {
   NavigateAndCommit(GURL(kTestUrl1));
 
-  RenderFrameHost* main_frame = web_contents()->GetMainFrame();
+  RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
   RenderFrameHost* subframe = NavigateSubframe();
 
   SimulateShiftDelta(1.0, main_frame);
diff --git a/chrome/browser/page_load_metrics/observers/javascript_frameworks_ukm_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/javascript_frameworks_ukm_observer_browsertest.cc
index d5b4b0e..359e14b7 100644
--- a/chrome/browser/page_load_metrics/observers/javascript_frameworks_ukm_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/javascript_frameworks_ukm_observer_browsertest.cc
@@ -133,9 +133,12 @@
     waiter.AddPageExpectation(
         page_load_metrics::PageLoadMetricsTestWaiter::TimingField::kLoadEvent);
     GURL subframe_url = https_test_server()->GetURL(test_url);
-    content::RenderFrameHost* subframe = fenced_frame_helper_.CreateFencedFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        subframe_url);
+    content::RenderFrameHost* subframe =
+        fenced_frame_helper_.CreateFencedFrame(browser()
+                                                   ->tab_strip_model()
+                                                   ->GetActiveWebContents()
+                                                   ->GetPrimaryMainFrame(),
+                                               subframe_url);
     EXPECT_NE(nullptr, subframe);
     waiter.Wait();
     CloseAllTabs();
diff --git a/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer.cc
index 9c9714b..603b8ab9 100644
--- a/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer.cc
@@ -88,7 +88,7 @@
   // TODO(https://crbug.com/1190112): The code uses the primary FrameTree, but
   // this event may have been dispatched for a non-primary FrameTree.
   auto* web_contents = GetDelegate().GetWebContents();
-  auto* frame = web_contents->GetMainFrame();
+  auto* frame = web_contents->GetPrimaryMainFrame();
 
   predictor_tab_helper_->RecordFirstContentfulPaint(
       frame, GetDelegate().GetNavigationStart() +
diff --git a/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
index f13ac9e..316b9ff 100644
--- a/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
@@ -97,7 +97,7 @@
   ResetTest();
 
   NavigateAndCommit(GURL(kDefaultTestUrl));
-  content::RenderFrameHost* mainframe = web_contents()->GetMainFrame();
+  content::RenderFrameHost* mainframe = web_contents()->GetPrimaryMainFrame();
 
   SimulateEvents(mainframe, false /* simulate_play_media */,
                  false /* simulate_app_background */);
@@ -114,7 +114,7 @@
   ResetTest();
 
   NavigateAndCommit(GURL(kDefaultTestUrl));
-  content::RenderFrameHost* mainframe = web_contents()->GetMainFrame();
+  content::RenderFrameHost* mainframe = web_contents()->GetPrimaryMainFrame();
 
   SimulateEvents(mainframe, true /* simulate_play_media */,
                  false /* simulate_app_background */);
@@ -134,7 +134,7 @@
   ResetTest();
 
   NavigateAndCommit(GURL(kDefaultTestUrl));
-  content::RenderFrameHost* mainframe = web_contents()->GetMainFrame();
+  content::RenderFrameHost* mainframe = web_contents()->GetPrimaryMainFrame();
 
   SimulateEvents(mainframe, true /* simulate_play_media */,
                  true /* simulate_app_background */);
@@ -154,7 +154,7 @@
   ResetTest();
 
   NavigateAndCommit(GURL(kDefaultTestUrl));
-  content::RenderFrameHost* mainframe = web_contents()->GetMainFrame();
+  content::RenderFrameHost* mainframe = web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* subframe =
       content::RenderFrameHostTester::For(mainframe)->AppendChild("subframe");
   std::unique_ptr<content::NavigationSimulator> simulator =
@@ -180,7 +180,7 @@
   ResetTest();
 
   NavigateAndCommit(GURL(kDefaultTestUrl));
-  content::RenderFrameHost* mainframe = web_contents()->GetMainFrame();
+  content::RenderFrameHost* mainframe = web_contents()->GetPrimaryMainFrame();
   content::RenderFrameHost* subframe =
       content::RenderFrameHostTester::For(mainframe)->AppendFencedFrame();
   std::unique_ptr<content::NavigationSimulator> simulator =
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
index a00447a..f40e3fc 100644
--- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
@@ -679,7 +679,7 @@
       https_test_server()->GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   histogram_tester()->ExpectTotalCount("Security.SecurityLevel.OnCommit", 1);
diff --git a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
index 7d6be97..01878e1 100644
--- a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
@@ -171,7 +171,7 @@
 TEST_F(SessionRestorePageLoadMetricsObserverTest,
        FirstPaintsOutOfSessionRestore) {
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GetTestURL(), web_contents()->GetMainFrame());
+      GetTestURL(), web_contents()->GetPrimaryMainFrame());
   ASSERT_NO_FATAL_FAILURE(SimulateTimingUpdateForTab(web_contents()));
   ExpectFirstPaintMetricsTotalCount(0);
   auto entries =
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc
index b4b14f9..12508e1 100644
--- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc
@@ -67,7 +67,7 @@
   auto* third_party_info = GetThirdPartyInfo(
       render_frame_host->GetLastCommittedURL(),
       content::WebContents::FromRenderFrameHost(render_frame_host)
-          ->GetMainFrame()
+          ->GetPrimaryMainFrame()
           ->GetLastCommittedURL(),
       is_third_party);
 
@@ -182,7 +182,7 @@
   // Report the feature usage if there's anything to report.
   if (third_party_storage_features.size() > 0) {
     page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage(
-        GetDelegate().GetWebContents()->GetMainFrame(),
+        GetDelegate().GetWebContents()->GetPrimaryMainFrame(),
         std::move(third_party_storage_features));
   }
 }
@@ -233,7 +233,7 @@
 
   // Filter out first-party frames.
   content::RenderFrameHost* top_frame =
-      GetDelegate().GetWebContents()->GetMainFrame();
+      GetDelegate().GetWebContents()->GetPrimaryMainFrame();
   if (!top_frame)
     return;
 
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
index 5a51f8d4..a802d1b9 100644
--- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
@@ -162,7 +162,7 @@
   void TriggerFrameActivation() {
     // Activate one frame by executing a dummy script.
     content::RenderFrameHost* ad_frame =
-        ChildFrameAt(web_contents()->GetMainFrame(), 0);
+        ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
     const std::string no_op_script = "// No-op script";
     EXPECT_TRUE(ExecuteScript(ad_frame, no_op_script));
   }
@@ -364,7 +364,7 @@
   NavigateToPageWithFrame("a.com");  // Same origin cookie read.
   NavigateFrameTo("a.com", "/empty.html");
   content::RenderFrameHost* frame =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
 
   // Write a first-party cookie.
   EXPECT_TRUE(content::ExecJs(frame, "document.cookie = 'foo=bar';"));
@@ -392,7 +392,7 @@
   NavigateToPageWithFrame("a.com");  // Same origin cookie read.
   NavigateFrameTo("b.com", "/empty.html");
   content::RenderFrameHost* frame =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
 
   // Write a third-party cookie.
   EXPECT_TRUE(content::ExecJs(
@@ -421,7 +421,7 @@
   NavigateToPageWithFrame("a.com");  // Same origin cookie read.
   NavigateFrameTo("b.com", "/empty.html");
   content::RenderFrameHost* frame =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
 
   // Read a third-party cookie.
   EXPECT_TRUE(content::ExecJs(frame, "let x = document.cookie;"));
@@ -447,7 +447,7 @@
   NavigateToPageWithFrame("a.com");  // Same origin cookie read.
   NavigateFrameTo("b.com", "/empty.html");
   content::RenderFrameHost* frame =
-      ChildFrameAt(web_contents()->GetMainFrame(), 0);
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
 
   // Write a third-party cookie.
   EXPECT_TRUE(content::ExecJs(
@@ -490,7 +490,8 @@
   base::HistogramTester histogram_tester;
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("a.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateToUntrackedUrl();
 
@@ -502,7 +503,8 @@
   base::HistogramTester histogram_tester;
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateToUntrackedUrl();
 
@@ -514,11 +516,13 @@
   base::HistogramTester histogram_tester;
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateFrameTo("c.com", "/empty.html");
   NavigateFrameTo("b.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateToUntrackedUrl();
 
@@ -530,10 +534,12 @@
   base::HistogramTester histogram_tester;
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateFrameTo("c.com", "/empty.html");
-  InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0));
+  InvokeStorageAccessOnFrame(
+      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));
 
   NavigateToUntrackedUrl();
 
@@ -559,8 +565,8 @@
     base::HistogramTester histogram_tester;
     NavigateToPageWithFrame("a.com");
     NavigateFrameTo("a.com", "/empty.html");
-    InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0),
-                               test_case);
+    InvokeStorageAccessOnFrame(
+        ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0), test_case);
     NavigateToUntrackedUrl();
 
     histogram_tester.ExpectBucketCount("Blink.UseCounter.Features",
@@ -585,8 +591,8 @@
     base::HistogramTester histogram_tester;
     NavigateToPageWithFrame("a.com");
     NavigateFrameTo("b.com", "/empty.html");
-    InvokeStorageAccessOnFrame(ChildFrameAt(web_contents()->GetMainFrame(), 0),
-                               test_case);
+    InvokeStorageAccessOnFrame(
+        ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0), test_case);
     NavigateToUntrackedUrl();
 
     histogram_tester.ExpectBucketCount("Blink.UseCounter.Features",
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc
index 93228c2..eb19650a 100644
--- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc
@@ -55,7 +55,7 @@
 
   // Returns the final RenderFrameHost after navigation commits.
   content::RenderFrameHost* NavigateMainFrame(const std::string& url) {
-    return NavigateFrame(url, web_contents()->GetMainFrame());
+    return NavigateFrame(url, web_contents()->GetPrimaryMainFrame());
   }
 
   // Returns the final RenderFrameHost after navigation commits.
diff --git a/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_browsertest.cc
index 91ad3d4..2323ed61 100644
--- a/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_browsertest.cc
@@ -31,7 +31,7 @@
 
  protected:
   content::RenderFrameHost* top_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter>
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index 8bbd9c0..a30846e 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -421,7 +421,7 @@
   }
 
   content::RenderFrameHost* RenderFrameHost() const {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
@@ -3274,7 +3274,7 @@
   // main frame.
   waiter->AddMainFrameIntersectionExpectation(gfx::Rect(110, 110, 190, 190));
   content::RenderFrameHost* child_frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       ExecJs(child_frame, "createIframeAtRect(\"test2\", 10, 10, 300, 300);"));
 
@@ -3327,7 +3327,7 @@
   // main frame.
   waiter->AddMainFrameIntersectionExpectation(gfx::Rect(110, 110, 140, 140));
   content::RenderFrameHost* child_frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       ExecJs(child_frame, "createIframeAtRect(\"test2\", 10, 10, 300, 300);"));
 
@@ -3368,7 +3368,7 @@
   // frame's viewport.
   waiter->AddMainFrameIntersectionExpectation(gfx::Rect(0, 0, 0, 0));
   content::RenderFrameHost* child_frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(ExecJs(child_frame,
                      "createIframeAtRect(\"test2\", 5000, 5000, 190, 190);"));
 
@@ -3410,7 +3410,7 @@
   // frame's viewport.
   waiter->AddMainFrameIntersectionExpectation(gfx::Rect(0, 0, 0, 0));
   content::RenderFrameHost* child_frame =
-      content::ChildFrameAt(web_contents->GetMainFrame(), 0);
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(ExecJs(child_frame,
                      "createIframeAtRect(\"test2\", 5000, 5000, 190, 190);"));
   waiter->Wait();
@@ -4086,7 +4086,7 @@
   bool back_forward_cache_enabled = GetParam() == kEnabled;
   // Navigate to A.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHostWrapper rfh_a(web_contents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh_a(web_contents()->GetPrimaryMainFrame());
 
   // Navigate to B.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
@@ -4148,7 +4148,7 @@
   bool back_forward_cache_enabled = GetParam() == kEnabled;
   // Navigate to A.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHostWrapper rfh_a(web_contents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh_a(web_contents()->GetPrimaryMainFrame());
 
   // Navigate to B.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
@@ -4191,7 +4191,7 @@
   bool back_forward_cache_enabled = GetParam() == kEnabled;
   // Navigate to A.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHostWrapper rfh_a(web_contents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh_a(web_contents()->GetPrimaryMainFrame());
 
   // Navigate to B.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
diff --git a/chrome/browser/paint_preview/paint_preview_browsertest.cc b/chrome/browser/paint_preview/paint_preview_browsertest.cc
index f77b822e..d02e497 100644
--- a/chrome/browser/paint_preview/paint_preview_browsertest.cc
+++ b/chrome/browser/paint_preview/paint_preview_browsertest.cc
@@ -191,7 +191,7 @@
   auto* client = PaintPreviewClient::FromWebContents(GetWebContents());
   WaitForLoadStopWithoutSuccessCheck();
   client->CapturePaintPreview(
-      params, GetWebContents()->GetMainFrame(),
+      params, GetWebContents()->GetPrimaryMainFrame(),
       base::BindOnce(
           [](base::RepeatingClosure quit,
              const PaintPreviewClient::PaintPreviewParams& params,
@@ -232,7 +232,7 @@
   auto* client = PaintPreviewClient::FromWebContents(GetWebContents());
   WaitForLoadStopWithoutSuccessCheck();
   client->CapturePaintPreview(
-      params, GetWebContents()->GetMainFrame(),
+      params, GetWebContents()->GetPrimaryMainFrame(),
       base::BindOnce(
           [](base::RepeatingClosure quit,
              const PaintPreviewClient::PaintPreviewParams& params,
@@ -278,7 +278,8 @@
 IN_PROC_BROWSER_TEST_P(PaintPreviewFencedFrameBrowserTest,
                        CaptureMainFrameWithCrossProcessFencedFrames) {
   LoadPage(http_server_.GetURL("a.com", "/title1.html"));
-  content::RenderFrameHost* primary_main_rfh = GetWebContents()->GetMainFrame();
+  content::RenderFrameHost* primary_main_rfh =
+      GetWebContents()->GetPrimaryMainFrame();
 
   // Create two fenced frames.
   fenced_frame_test_helper().CreateFencedFrame(
@@ -329,7 +330,8 @@
   base::ScopedAllowBlockingForTesting scope;
 
   LoadPage(http_server_.GetURL("a.com", "/title1.html"));
-  content::RenderFrameHost* primary_main_rfh = GetWebContents()->GetMainFrame();
+  content::RenderFrameHost* primary_main_rfh =
+      GetWebContents()->GetPrimaryMainFrame();
 
   // Create two fenced frames.
   content::RenderFrameHostWrapper fenced_rfh_wrapper(
@@ -417,7 +419,7 @@
   auto* client = PaintPreviewClient::FromWebContents(GetWebContents());
   WaitForLoadStopWithoutSuccessCheck();
   client->CapturePaintPreview(
-      params, GetWebContents()->GetMainFrame(),
+      params, GetWebContents()->GetPrimaryMainFrame(),
       base::BindOnce(
           [](base::RepeatingClosure quit,
              const PaintPreviewClient::PaintPreviewParams& params,
@@ -471,7 +473,7 @@
   auto* client = PaintPreviewClient::FromWebContents(GetWebContents());
   WaitForLoadStopWithoutSuccessCheck();
   client->CapturePaintPreview(
-      params, GetWebContents()->GetMainFrame(),
+      params, GetWebContents()->GetPrimaryMainFrame(),
       base::BindOnce(
           [](base::RepeatingClosure quit,
              const PaintPreviewClient::PaintPreviewParams& params,
@@ -515,7 +517,7 @@
   base::RunLoop started_loop;
   NoOpPaintPreviewRecorder noop_recorder;
   noop_recorder.SetRequestedClosure(started_loop.QuitClosure());
-  OverrideInterface(&noop_recorder, GetWebContents()->GetMainFrame());
+  OverrideInterface(&noop_recorder, GetWebContents()->GetPrimaryMainFrame());
 
   CreateClient();
   auto* client = PaintPreviewClient::FromWebContents(web_contents);
@@ -533,7 +535,7 @@
   auto params = MakeParams();
   bool did_run = false;
   client->CapturePaintPreview(
-      params, web_contents->GetMainFrame(),
+      params, web_contents->GetPrimaryMainFrame(),
       // This callback is now posted so it shouldn't cause a crash.
       base::BindOnce(
           [](content::WebContents* web_contents, bool* did_run_ptr,
@@ -560,7 +562,7 @@
 
   // Crash the renderer.
   content::RenderProcessHost* process =
-      GetWebContents()->GetMainFrame()->GetProcess();
+      GetWebContents()->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   process->Shutdown(0);
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
index 1e789ad..263284c 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
@@ -146,10 +146,11 @@
 
   auto key = file_manager->CreateKey(tab_id);
   auto it = tasks_.emplace(
-      tab_id, std::make_unique<TabServiceTask>(
-                  tab_id, key, contents->GetMainFrame()->GetFrameTreeNodeId(),
-                  contents->GetMainFrame()->GetGlobalId(), page_scale_factor, x,
-                  y, std::move(capture_handle)));
+      tab_id,
+      std::make_unique<TabServiceTask>(
+          tab_id, key, contents->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
+          contents->GetPrimaryMainFrame()->GetGlobalId(), page_scale_factor, x,
+          y, std::move(capture_handle)));
   if (!it.second) {
     std::move(callback).Run(Status::kCaptureInProgress);
     return;
@@ -293,7 +294,7 @@
       content::WebContents::FromFrameTreeNodeId(task->frame_tree_node_id());
   auto* rfh = content::RenderFrameHost::FromID(task->frame_routing_id());
   if (!contents || !rfh || contents->IsBeingDestroyed() ||
-      contents->GetMainFrame() != rfh || !rfh->IsActive() ||
+      contents->GetPrimaryMainFrame() != rfh || !rfh->IsActive() ||
       !rfh->IsRenderFrameLive()) {
     task->OnCaptured(Status::kWebContentsGone);
     return;
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
index eb4fa94..2208c80 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
@@ -104,7 +104,7 @@
 
   void OverrideInterface(MockPaintPreviewRecorder* recorder) {
     blink::AssociatedInterfaceProvider* remote_interfaces =
-        web_contents()->GetMainFrame()->GetRemoteAssociatedInterfaces();
+        web_contents()->GetPrimaryMainFrame()->GetRemoteAssociatedInterfaces();
     remote_interfaces->OverrideBinderForTesting(
         mojom::PaintPreviewRecorder::Name_,
         base::BindRepeating(&MockPaintPreviewRecorder::BindRequest,
diff --git a/chrome/browser/password_manager/android/account_chooser_dialog_android.cc b/chrome/browser/password_manager/android/account_chooser_dialog_android.cc
index 5472316f..3b3038f 100644
--- a/chrome/browser/password_manager/android/account_chooser_dialog_android.cc
+++ b/chrome/browser/password_manager/android/account_chooser_dialog_android.cc
@@ -167,7 +167,7 @@
   for (const auto& form : local_credentials_forms()) {
     FetchAvatar(dialog_jobject_, form.get(), avatar_index++,
                 loader_factory.get(),
-                web_contents_->GetMainFrame()->GetLastCommittedOrigin());
+                web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
   return true;
 }
diff --git a/chrome/browser/password_manager/android/password_manager_android_browsertest.cc b/chrome/browser/password_manager/android/password_manager_android_browsertest.cc
index 7dee464..5abe5dd 100644
--- a/chrome/browser/password_manager/android/password_manager_android_browsertest.cc
+++ b/chrome/browser/password_manager/android/password_manager_android_browsertest.cc
@@ -84,7 +84,8 @@
       password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
           GetActiveWebContents());
   password_manager::ContentPasswordManagerDriver* driver =
-      driver_factory->GetDriverForFrame(GetActiveWebContents()->GetMainFrame());
+      driver_factory->GetDriverForFrame(
+          GetActiveWebContents()->GetPrimaryMainFrame());
 
   PasswordsNavigationObserver observer(GetActiveWebContents());
   observer.SetPathToWaitFor("/password/done.html");
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 1006d5ed1..769ab63 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -656,7 +656,7 @@
 
   auto metrics_recorder = std::make_unique<
       password_manager::metrics_util::LeakDialogMetricsRecorder>(
-      web_contents()->GetMainFrame()->GetPageUkmSourceId(),
+      web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
       password_manager::GetLeakDialogType(leak_type));
   (new CredentialLeakControllerAndroid(
        leak_type, url, username, GetPasswordChangeSuccessTracker(),
@@ -815,7 +815,7 @@
       autofill::ContentAutofillDriverFactory::FromWebContents(web_contents());
   if (factory) {
     autofill::ContentAutofillDriver* driver =
-        factory->DriverForFrame(web_contents()->GetMainFrame());
+        factory->DriverForFrame(web_contents()->GetPrimaryMainFrame());
     // |driver| can be NULL if the tab is being closed.
     if (driver) {
       autofill::AutofillManager* autofill_manager = driver->autofill_manager();
@@ -828,7 +828,7 @@
 
 bool ChromePasswordManagerClient::IsCommittedMainFrameSecure() const {
   return network::IsOriginPotentiallyTrustworthy(
-      web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+      web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 const GURL& ChromePasswordManagerClient::GetLastCommittedURL() const {
@@ -837,7 +837,7 @@
 
 url::Origin ChromePasswordManagerClient::GetLastCommittedOrigin() const {
   DCHECK(web_contents());
-  return web_contents()->GetMainFrame()->GetLastCommittedOrigin();
+  return web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
 }
 const password_manager::CredentialsFilter*
 ChromePasswordManagerClient::GetStoreResultFilter() const {
@@ -965,7 +965,7 @@
 #endif
 
 ukm::SourceId ChromePasswordManagerClient::GetUkmSourceId() {
-  return web_contents()->GetMainFrame()->GetPageUkmSourceId();
+  return web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 }
 
 PasswordManagerMetricsRecorder*
@@ -1256,7 +1256,7 @@
 
   // Only valid for the currently committed RenderFrameHost, and not, e.g. old
   // zombie RFH's being swapped out following cross-origin navigations.
-  if (web_contents->GetMainFrame() != render_frame_host)
+  if (web_contents->GetPrimaryMainFrame() != render_frame_host)
     return;
 
   // The ChromePasswordManagerClient will not bind the mojo interface for
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index f54e80e..e7d8dfc7 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -270,7 +270,7 @@
   ChromeRenderViewHostTestHarness::SetUp();
 
   blink::AssociatedInterfaceProvider* remote_interfaces =
-      web_contents()->GetMainFrame()->GetRemoteAssociatedInterfaces();
+      web_contents()->GetPrimaryMainFrame()->GetRemoteAssociatedInterfaces();
   remote_interfaces->OverrideBinderForTesting(
       autofill::mojom::PasswordAutofillAgent::Name_,
       base::BindRepeating(&FakePasswordAutofillAgent::BindReceiver,
@@ -760,7 +760,7 @@
 
   // This call should not crash.
   ChromePasswordManagerClient::BindCredentialManager(
-      web_contents->GetMainFrame(), mojo::NullReceiver());
+      web_contents->GetPrimaryMainFrame(), mojo::NullReceiver());
 }
 
 TEST_F(ChromePasswordManagerClientTest, CanShowBubbleOnURL) {
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
index 64fc913..8257010 100644
--- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
@@ -83,7 +83,7 @@
 #if !BUILDFLAG(IS_ANDROID)
     authenticator_request_delegate_ =
         AuthenticatorRequestScheduler::CreateRequestDelegate(
-            web_contents()->GetMainFrame());
+            web_contents()->GetPrimaryMainFrame());
     // Setting the RPID creates the dialog model.
     authenticator_request_delegate_->SetRelyingPartyId("rpId");
 #else
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc
index a6fa3fd..8449fb1 100644
--- a/chrome/browser/password_manager/credential_manager_browsertest.cc
+++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -244,7 +244,7 @@
     // Trigger a cross-site navigation that is carried out in a new renderer,
     // and which will swap out the old RenderFrameHost.
     content::RenderFrameDeletedObserver rfh_destruction_observer(
-        WebContents()->GetMainFrame());
+        WebContents()->GetPrimaryMainFrame());
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), b_url));
 
     // Ensure that the navigator.credentials.store() call is never serviced.
diff --git a/chrome/browser/password_manager/password_generation_interactive_uitest.cc b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
index 06f8fbe..4cda357 100644
--- a/chrome/browser/password_manager/password_generation_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
@@ -124,7 +124,7 @@
         blink::WebInputEvent::GetStaticTimeStampForTests());
     event.windows_key_code = key;
     WebContents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->ForwardKeyboardEvent(event);
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 75e614b6..a118cfa 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -147,7 +147,8 @@
   }
 
   bool IsGetCredentialsSuccessful() {
-    return "success" == content::EvalJs(WebContents()->GetMainFrame(), R"(
+    return "success" ==
+           content::EvalJs(WebContents()->GetPrimaryMainFrame(), R"(
       new Promise(resolve => {
         navigator.credentials.get({password: true, unmediated: true })
           .then(m => { resolve("success"); })
@@ -1235,7 +1236,7 @@
       autofill::ChromeAutofillClient::FromWebContents(WebContents());
   autofill_client->PropagateAutofillPredictions(
       autofill::ContentAutofillDriver::GetForRenderFrameHost(
-          WebContents()->GetMainFrame()),
+          WebContents()->GetPrimaryMainFrame()),
       {&form_structure});
 
   // Check original values before interaction
@@ -1299,7 +1300,7 @@
       autofill::ChromeAutofillClient::FromWebContents(WebContents());
   autofill_client->PropagateAutofillPredictions(
       autofill::ContentAutofillDriver::GetForRenderFrameHost(
-          WebContents()->GetMainFrame()),
+          WebContents()->GetPrimaryMainFrame()),
       {&form_structure});
 
   // Check original values before interaction
@@ -2051,7 +2052,7 @@
   ObservingAutofillClient* observing_autofill_client =
       ObservingAutofillClient::FromWebContents(WebContents());
   password_manager::ContentPasswordManagerDriver* driver =
-      driver_factory->GetDriverForFrame(WebContents()->GetMainFrame());
+      driver_factory->GetDriverForFrame(WebContents()->GetPrimaryMainFrame());
   driver->GetPasswordAutofillManager()->set_autofill_client(
       observing_autofill_client);
 
@@ -3007,7 +3008,7 @@
       "window.domAutomationController.send(logs_found);";
   bool logs_found = false;
   ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
-      internals_web_contents->GetMainFrame(), find_logs, &logs_found));
+      internals_web_contents->GetPrimaryMainFrame(), find_logs, &logs_found));
   EXPECT_TRUE(logs_found);
 }
 
@@ -3030,7 +3031,7 @@
       "window.domAutomationController.send(logs_found);";
   bool logs_found = false;
   ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
-      internals_web_contents->GetMainFrame(), find_logs, &logs_found));
+      internals_web_contents->GetPrimaryMainFrame(), find_logs, &logs_found));
   EXPECT_TRUE(logs_found);
 }
 
@@ -3359,7 +3360,7 @@
   GURL submit_url(embedded_test_server()->GetURL("/password/done.html"));
   InjectBlankFrameWithPasswordForm(WebContents(), submit_url);
   content::RenderFrameHost* frame =
-      ChildFrameAt(WebContents()->GetMainFrame(), 0);
+      ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(GURL(url::kAboutBlankURL), frame->GetLastCommittedURL());
   EXPECT_TRUE(frame->IsRenderFrameLive());
   EXPECT_FALSE(prompt_observer.IsSavePromptAvailable());
@@ -3395,10 +3396,10 @@
 
   // Submit the password form and check that there was no renderer kill and no
   BubbleObserver prompt_observer(WebContents());
-  SubmitInjectedPasswordForm(newtab, newtab->GetMainFrame(), submit_url);
+  SubmitInjectedPasswordForm(newtab, newtab->GetPrimaryMainFrame(), submit_url);
   EXPECT_FALSE(prompt_observer.IsSavePromptAvailable());
-  EXPECT_TRUE(newtab->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_EQ(submit_url, newtab->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_TRUE(newtab->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_EQ(submit_url, newtab->GetPrimaryMainFrame()->GetLastCommittedURL());
 }
 
 // Verify that previously saved passwords for about:blank frames are not used
@@ -3423,7 +3424,7 @@
   // Inject an about:blank frame with password form.
   InjectBlankFrameWithPasswordForm(WebContents(), submit_url);
   content::RenderFrameHost* frame =
-      ChildFrameAt(WebContents()->GetMainFrame(), 0);
+      ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(GURL(url::kAboutBlankURL), frame->GetLastCommittedURL());
 
   // Simulate user interaction in the iframe which normally triggers
@@ -3469,7 +3470,7 @@
                                      inject_data_frame_with_password_form));
   EXPECT_TRUE(content::WaitForLoadStop(WebContents()));
   content::RenderFrameHost* frame =
-      ChildFrameAt(WebContents()->GetMainFrame(), 0);
+      ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame->GetLastCommittedURL().SchemeIs(url::kDataScheme));
   EXPECT_TRUE(frame->IsRenderFrameLive());
   EXPECT_FALSE(prompt_observer.IsSavePromptAvailable());
@@ -3478,7 +3479,7 @@
   // password prompt and shouldn't result in a renderer kill.
   SubmitInjectedPasswordForm(WebContents(), frame, submit_url);
   // After navigation, the RenderFrameHost may change.
-  frame = ChildFrameAt(WebContents()->GetMainFrame(), 0);
+  frame = ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame->IsRenderFrameLive());
   EXPECT_EQ(submit_url, frame->GetLastCommittedURL());
   EXPECT_FALSE(prompt_observer.IsSavePromptAvailable());
@@ -3801,7 +3802,7 @@
   ContentPasswordManagerDriverFactory* factory =
       ContentPasswordManagerDriverFactory::FromWebContents(WebContents());
   autofill::mojom::PasswordManagerDriver* driver =
-      factory->GetDriverForFrame(WebContents()->GetMainFrame());
+      factory->GetDriverForFrame(WebContents()->GetPrimaryMainFrame());
 
   // Just fake a position of the <input> element within the content_area_bounds.
   // For this test it does not matter where the dropdown is rendered.
@@ -3971,7 +3972,7 @@
                        SavePasswordOnRestoredPage) {
   // Navigate to a page with a password form.
   NavigateToFile("/password/password_form.html");
-  content::RenderFrameHostWrapper rfh(WebContents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh(WebContents()->GetPrimaryMainFrame());
 
   // Navigate away so that the password form page is stored in the cache.
   EXPECT_TRUE(NavigateToURL(
@@ -3982,7 +3983,7 @@
   // Restore the cached page.
   WebContents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(WebContents()));
-  EXPECT_EQ(rfh.get(), WebContents()->GetMainFrame());
+  EXPECT_EQ(rfh.get(), WebContents()->GetPrimaryMainFrame());
 
   // Fill out and submit the password form.
   PasswordsNavigationObserver observer(WebContents());
@@ -4011,7 +4012,7 @@
                        NotCachedIfCredentialsAPIUsed) {
   // Navigate to a page with a password form.
   NavigateToFile("/password/password_form.html");
-  content::RenderFrameHost* rfh = WebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = WebContents()->GetPrimaryMainFrame();
   content::RenderFrameDeletedObserver rfh_deleted_observer(rfh);
 
   // Use the password manager API, this should make the page uncacheable.
@@ -4028,7 +4029,7 @@
                        CredentialsAPIOnlyCalledOnRestoredPage) {
   // Navigate to a page with a password form.
   NavigateToFile("/password/password_form.html");
-  content::RenderFrameHostWrapper rfh(WebContents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh(WebContents()->GetPrimaryMainFrame());
 
   // Navigate away.
   EXPECT_TRUE(NavigateToURL(
@@ -4039,7 +4040,7 @@
   // Restore the cached page.
   WebContents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(WebContents()));
-  EXPECT_EQ(rfh.get(), WebContents()->GetMainFrame());
+  EXPECT_EQ(rfh.get(), WebContents()->GetPrimaryMainFrame());
 
   // Make sure the password manager API works. Since it was never connected, it
   // shouldn't have been affected by the
@@ -4060,7 +4061,7 @@
   GURL submit_url(embedded_test_server()->GetURL("/password/done.html"));
   InjectFrameWithPasswordForm(WebContents(), submit_url);
   content::RenderFrameHost* frame =
-      ChildFrameAt(WebContents()->GetMainFrame(), 0);
+      ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(GURL(url::kAboutBlankURL), frame->GetLastCommittedURL());
   EXPECT_EQ(submit_url.DeprecatedGetOriginAsURL(),
             frame->GetLastCommittedOrigin().GetURL());
@@ -4745,8 +4746,10 @@
   // Sets to ignore mouse events. Otherwise, OnInputEvent() could be called
   // multiple times if the mouse cursor is over on the test window during
   // testing.
-  web_contents()->GetMainFrame()->GetRenderWidgetHost()->AddMouseEventCallback(
-      base::BindRepeating(
+  web_contents()
+      ->GetPrimaryMainFrame()
+      ->GetRenderWidgetHost()
+      ->AddMouseEventCallback(base::BindRepeating(
           [](const blink::WebMouseEvent& event) { return true; }));
 
   EXPECT_CALL(
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index 224abec3..ff467e64 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -513,7 +513,7 @@
 
 content::RenderFrameHost* PasswordManagerBrowserTestBase::RenderFrameHost()
     const {
-  return WebContents()->GetMainFrame();
+  return WebContents()->GetPrimaryMainFrame();
 }
 
 void PasswordManagerBrowserTestBase::NavigateToFile(const std::string& path) {
diff --git a/chrome/browser/payments/android/payment_app_service_bridge_unittest.cc b/chrome/browser/payments/android/payment_app_service_bridge_unittest.cc
index de6b6958..ccb42cf 100644
--- a/chrome/browser/payments/android/payment_app_service_bridge_unittest.cc
+++ b/chrome/browser/payments/android/payment_app_service_bridge_unittest.cc
@@ -104,8 +104,9 @@
   MockCallback mock_callback;
   base::WeakPtr<PaymentAppServiceBridge> bridge =
       PaymentAppServiceBridge::Create(
-          /*number_of_factories=*/3, web_contents_->GetMainFrame(), top_origin_,
-          spec.AsWeakPtr(), /*twa_package_name=*/GetParam(), web_data_service_,
+          /*number_of_factories=*/3, web_contents_->GetPrimaryMainFrame(),
+          top_origin_, spec.AsWeakPtr(), /*twa_package_name=*/GetParam(),
+          web_data_service_,
           /*may_crawl_for_installable_payment_apps=*/true,
           /*is_off_the_record=*/false,
           base::BindRepeating(&MockCallback::NotifyCanMakePaymentCalculated,
@@ -126,7 +127,7 @@
   EXPECT_EQ(frame_origin_, bridge->GetFrameOrigin());
   EXPECT_EQ("https://merchant.example",
             bridge->GetFrameSecurityOrigin().Serialize());
-  EXPECT_EQ(web_contents_->GetMainFrame(),
+  EXPECT_EQ(web_contents_->GetPrimaryMainFrame(),
             bridge->GetInitiatorRenderFrameHost());
   EXPECT_EQ(2U, bridge->GetMethodData().size());
   EXPECT_EQ("basic-card", bridge->GetMethodData()[0]->supported_method);
diff --git a/chrome/browser/payments/empty_parameters_browsertest.cc b/chrome/browser/payments/empty_parameters_browsertest.cc
index ef12d1ed..f4ca842 100644
--- a/chrome/browser/payments/empty_parameters_browsertest.cc
+++ b/chrome/browser/payments/empty_parameters_browsertest.cc
@@ -33,7 +33,7 @@
     downloader->AddTestServerURL("https://kylepay.com/",
                                  kylepay_server_.GetURL("kylepay.com", "/"));
     ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        GetActiveWebContents()->GetMainFrame())
+        GetActiveWebContents()->GetPrimaryMainFrame())
         ->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
             std::move(downloader));
   }
diff --git a/chrome/browser/payments/ignore_payment_method_browsertest.cc b/chrome/browser/payments/ignore_payment_method_browsertest.cc
index fed39ff..43f9c8b 100644
--- a/chrome/browser/payments/ignore_payment_method_browsertest.cc
+++ b/chrome/browser/payments/ignore_payment_method_browsertest.cc
@@ -39,7 +39,7 @@
 
   ServiceWorkerPaymentAppFinder* GetFinder() {
     return ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        GetActiveWebContents()->GetMainFrame());
+        GetActiveWebContents()->GetPrimaryMainFrame());
   }
 
   std::string method_name_;
diff --git a/chrome/browser/payments/payment_handler_permission_context_unittest.cc b/chrome/browser/payments/payment_handler_permission_context_unittest.cc
index c4f58ea..85878014 100644
--- a/chrome/browser/payments/payment_handler_permission_context_unittest.cc
+++ b/chrome/browser/payments/payment_handler_permission_context_unittest.cc
@@ -83,8 +83,8 @@
   content::WebContentsTester::For(web_contents())->NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
   permission_context.RequestPermission(
       id, url, true,
diff --git a/chrome/browser/payments/service_worker_payment_app_finder_browsertest.cc b/chrome/browser/payments/service_worker_payment_app_finder_browsertest.cc
index ae2757c..4799bdd 100644
--- a/chrome/browser/payments/service_worker_payment_app_finder_browsertest.cc
+++ b/chrome/browser/payments/service_worker_payment_app_finder_browsertest.cc
@@ -184,7 +184,10 @@
         browser(), alicepay_.GetURL("chromium.org", "/")));
 
     auto* finder = ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+        browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame());
     finder->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
         std::move(downloader));
 
diff --git a/chrome/browser/payments/site_per_process_payments_browsertest.cc b/chrome/browser/payments/site_per_process_payments_browsertest.cc
index 97d74ff..9a5d128 100644
--- a/chrome/browser/payments/site_per_process_payments_browsertest.cc
+++ b/chrome/browser/payments/site_per_process_payments_browsertest.cc
@@ -77,9 +77,10 @@
   EXPECT_TRUE(content::ExecJs(iframe, "triggerPaymentRequest()"));
 
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
-  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(frame);
-  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(frame->GetSiteInstance(),
+            tab->GetPrimaryMainFrame()->GetSiteInstance());
 }
 
 }  // namespace payments
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index f62253b..f37c539 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -349,7 +349,8 @@
   }
 
   content::RenderFrameHost* GetPluginFrame(WebContents* guest_contents) const {
-    return pdf_frame_util::FindPdfChildFrame(guest_contents->GetMainFrame());
+    return pdf_frame_util::FindPdfChildFrame(
+        guest_contents->GetPrimaryMainFrame());
   }
 
   // Finds the `RenderFrameHost`s of PDF plugin frames within a given
@@ -595,7 +596,8 @@
 
   // Start loading another PDF in the new tab, but pause during guest attach.
   // It is important that the PDF navigation uses the same RFH as `delayer`.
-  InnerWebContentsAttachDelayer delayer(new_web_contents->GetMainFrame());
+  InnerWebContentsAttachDelayer delayer(
+      new_web_contents->GetPrimaryMainFrame());
   content::TestNavigationObserver navigation_observer(new_web_contents);
   new_web_contents->GetController().LoadURLWithParams(
       content::NavigationController::LoadURLParams(main_url));
@@ -1573,7 +1575,7 @@
 
   GURL unfiltered_valid_link_url(valid_link_url);
   content::RenderProcessHost* rph =
-      guest_contents->GetMainFrame()->GetProcess();
+      guest_contents->GetPrimaryMainFrame()->GetProcess();
   rph->FilterURL(true, &valid_link_url);
   rph->FilterURL(true, &invalid_link_url);
 
@@ -2050,14 +2052,15 @@
 
   // Makes sure that the correct frame invoked the context menu.
   content::ContextMenuInterceptor menu_interceptor(
-      guest_contents->GetMainFrame());
+      guest_contents->GetPrimaryMainFrame());
 
   // Executes the print command as soon as the context menu is shown.
   ContextMenuNotificationObserver context_menu_observer(IDC_PRINT);
 
   PrintObserver print_observer(guest_contents, plugin_frame);
-  guest_contents->GetMainFrame()->GetRenderWidgetHost()->ShowContextMenuAtPoint(
-      {1, 1}, ui::MENU_SOURCE_MOUSE);
+  guest_contents->GetPrimaryMainFrame()
+      ->GetRenderWidgetHost()
+      ->ShowContextMenuAtPoint({1, 1}, ui::MENU_SOURCE_MOUSE);
   print_observer.WaitForPrintPreview();
   menu_interceptor.Wait();
 }
@@ -2071,7 +2074,7 @@
 
   // Makes sure that the correct frame invoked the context menu.
   content::ContextMenuInterceptor menu_interceptor(
-      guest_contents->GetMainFrame());
+      guest_contents->GetPrimaryMainFrame());
 
   // Executes the print command as soon as the context menu is shown.
   ContextMenuNotificationObserver context_menu_observer(IDC_PRINT);
@@ -2080,8 +2083,9 @@
   content::SimulateMouseClickAt(guest_contents,
                                 blink::WebInputEvent::kNoModifiers,
                                 blink::WebMouseEvent::Button::kLeft, {1, 1});
-  guest_contents->GetMainFrame()->GetRenderWidgetHost()->ShowContextMenuAtPoint(
-      {1, 1}, ui::MENU_SOURCE_MOUSE);
+  guest_contents->GetPrimaryMainFrame()
+      ->GetRenderWidgetHost()
+      ->ShowContextMenuAtPoint({1, 1}, ui::MENU_SOURCE_MOUSE);
   print_observer.WaitForPrintPreview();
   menu_interceptor.Wait();
 }
@@ -2162,13 +2166,14 @@
 
   // Makes sure that the correct frame invoked the context menu.
   content::ContextMenuInterceptor menu_interceptor(
-      guest_contents->GetMainFrame());
+      guest_contents->GetPrimaryMainFrame());
 
   // Captures the command IDs of the context menu.
   ContextMenuWaiter menu_observer;
 
-  guest_contents->GetMainFrame()->GetRenderWidgetHost()->ShowContextMenuAtPoint(
-      {1, 1}, ui::MENU_SOURCE_MOUSE);
+  guest_contents->GetPrimaryMainFrame()
+      ->GetRenderWidgetHost()
+      ->ShowContextMenuAtPoint({1, 1}, ui::MENU_SOURCE_MOUSE);
 
   menu_observer.WaitForMenuOpenAndClose();
   menu_interceptor.Wait();
@@ -2598,7 +2603,7 @@
       GetPluginFrames(guest_contents);
   ASSERT_EQ(plugin_frames.size(), 1u);
   EXPECT_NE(plugin_frames[0]->GetProcess(),
-            guest_contents->GetMainFrame()->GetProcess());
+            guest_contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 IN_PROC_BROWSER_TEST_P(PDFExtensionIsolatedContentTest, HistoryNavigation) {
@@ -4601,7 +4606,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_helper().CreateFencedFrame(
-          GetActiveWebContents()->GetMainFrame(), fenced_frame_url);
+          GetActiveWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
@@ -4621,11 +4626,24 @@
       GetActiveWebContents(), embedded_test_server()->GetURL("/empty.html")));
 
   // Create a fenced frame and try to navigate to a PDF.
-  EXPECT_NE(nullptr,
-            fenced_frame_helper().CreateFencedFrame(
-                GetActiveWebContents()->GetMainFrame(),
-                embedded_test_server()->GetURL("/pdf/test-fenced-frame.pdf"),
-                net::Error::ERR_BLOCKED_BY_CLIENT));
+  EXPECT_TRUE(fenced_frame_helper().CreateFencedFrame(
+      GetActiveWebContents()->GetPrimaryMainFrame(),
+      embedded_test_server()->GetURL("/pdf/test-fenced-frame.pdf"),
+      net::Error::ERR_BLOCKED_BY_CLIENT));
+  EXPECT_EQ(CountPDFProcesses(), 0);
+}
+
+// Like `LoadPdfInFencedFrame`, but without Supports-Loading-Mode headers set.
+IN_PROC_BROWSER_TEST_F(PDFExtensionPrerenderAndFencedFrameTest,
+                       LoadPdfInFencedFrameWithoutFencedFrameOptIn) {
+  ASSERT_TRUE(content::NavigateToURL(
+      GetActiveWebContents(), embedded_test_server()->GetURL("/empty.html")));
+
+  // Create a fenced frame and try to navigate to a PDF.
+  EXPECT_TRUE(fenced_frame_helper().CreateFencedFrame(
+      GetActiveWebContents()->GetPrimaryMainFrame(),
+      embedded_test_server()->GetURL("/pdf/test.pdf"),
+      net::Error::ERR_BLOCKED_BY_RESPONSE));
   EXPECT_EQ(CountPDFProcesses(), 0);
 }
 
@@ -4639,7 +4657,7 @@
   // Create a fenced frame for loading a document with pdf embed(s).
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_helper().CreateFencedFrame(
-          GetActiveWebContents()->GetMainFrame(),
+          GetActiveWebContents()->GetPrimaryMainFrame(),
           embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   ASSERT_TRUE(fenced_frame_host);
 
diff --git a/chrome/browser/performance_hints/performance_hints_observer.cc b/chrome/browser/performance_hints/performance_hints_observer.cc
index 971bcca..9276ef7 100644
--- a/chrome/browser/performance_hints/performance_hints_observer.cc
+++ b/chrome/browser/performance_hints/performance_hints_observer.cc
@@ -298,7 +298,7 @@
   // The error pages do not support hints.
   const GURL page_url = GetWebContents().GetLastCommittedURL();
   return page_url.is_valid() && page_url.SchemeIsHTTPOrHTTPS() &&
-         !GetWebContents().GetMainFrame()->IsErrorDocument();
+         !GetWebContents().GetPrimaryMainFrame()->IsErrorDocument();
 }
 
 void PerformanceHintsObserver::PopulateLinkHints(PageData& page_data) {
diff --git a/chrome/browser/performance_hints/performance_hints_observer_browsertest.cc b/chrome/browser/performance_hints/performance_hints_observer_browsertest.cc
index d0bb8cd0..627a2fe1 100644
--- a/chrome/browser/performance_hints/performance_hints_observer_browsertest.cc
+++ b/chrome/browser/performance_hints/performance_hints_observer_browsertest.cc
@@ -119,7 +119,7 @@
                      optimization_guide::proto::PERFORMANCE_FAST);
 
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(), fenced_frame_url));
+      web_contents()->GetPrimaryMainFrame(), fenced_frame_url));
 
   // The fenced frame URL has a hint for Google, but is not fetched.
   EXPECT_THAT(PerformanceHintsObserver::PerformanceClassForURL(
diff --git a/chrome/browser/performance_manager/mechanisms/page_freezer.cc b/chrome/browser/performance_manager/mechanisms/page_freezer.cc
index 93019fc..62bf9ec 100644
--- a/chrome/browser/performance_manager/mechanisms/page_freezer.cc
+++ b/chrome/browser/performance_manager/mechanisms/page_freezer.cc
@@ -36,7 +36,8 @@
   // it's in background. This information isn't available in the PM graph, this
   // has to be checked on the UI thread.
   if (permission_controller->GetPermissionStatusForCurrentDocument(
-          blink::PermissionType::NOTIFICATIONS, contents->GetMainFrame()) ==
+          blink::PermissionType::NOTIFICATIONS,
+          contents->GetPrimaryMainFrame()) ==
       blink::mojom::PermissionStatus::GRANTED) {
     return;
   }
diff --git a/chrome/browser/performance_manager/observers/page_load_metrics_observer_browsertest.cc b/chrome/browser/performance_manager/observers/page_load_metrics_observer_browsertest.cc
index 40b71ab..4fc35b3 100644
--- a/chrome/browser/performance_manager/observers/page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/performance_manager/observers/page_load_metrics_observer_browsertest.cc
@@ -148,7 +148,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
 
   entries = test_ukm_recorder()->GetEntriesByName(
       ukm::builders::LoadCountsPerTopLevelDocument::kEntryName);
diff --git a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
index a2dacb0..eb76d9b 100644
--- a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
+++ b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
@@ -74,7 +74,8 @@
 
     bool has_notifications_permission =
         permission_controller->GetPermissionStatusForCurrentDocument(
-            blink::PermissionType::NOTIFICATIONS, content->GetMainFrame()) ==
+            blink::PermissionType::NOTIFICATIONS,
+            content->GetPrimaryMainFrame()) ==
         blink::mojom::PermissionStatus::GRANTED;
 
     BackgroundTabLoadingPolicy::PageNodeAndNotificationPermission
diff --git a/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc b/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc
index adfc4ae..13ba8481 100644
--- a/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc
+++ b/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc
@@ -148,7 +148,7 @@
   }
 
   content::RenderFrameHost* top_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   void VerifyEvictionExpectation(
diff --git a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc
index 7e56f2b..b1d2217 100644
--- a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc
+++ b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc
@@ -139,7 +139,7 @@
     NavigateAndCommit(url);
     auto request = std::make_unique<permissions::MockPermissionRequest>(
         url, permissions::RequestType::kGeolocation);
-    manager_->AddRequest(web_contents()->GetMainFrame(), request.get());
+    manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), request.get());
     return request;
   }
 #endif
@@ -156,7 +156,7 @@
 TEST_F(ChromePermissionRequestManagerTest, UMAForSimpleAcceptedGestureBubble) {
   base::HistogramTester histograms;
 
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request1_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
   WaitForBubbleToBeShown();
   histograms.ExpectUniqueSample(
       permissions::PermissionUmaUtil::kPermissionsPromptShown,
@@ -195,7 +195,7 @@
 TEST_F(ChromePermissionRequestManagerTest, UMAForSimpleDeniedNoGestureBubble) {
   base::HistogramTester histograms;
 
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request2_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
   WaitForBubbleToBeShown();
 
   histograms.ExpectTotalCount(
@@ -234,8 +234,8 @@
 TEST_F(ChromePermissionRequestManagerTest, UMAForMergedAcceptedBubble) {
   base::HistogramTester histograms;
 
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_mic_);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_camera_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
   WaitForBubbleToBeShown();
 
   histograms.ExpectUniqueSample(
@@ -265,8 +265,8 @@
 TEST_F(ChromePermissionRequestManagerTest, UMAForMergedDeniedBubble) {
   base::HistogramTester histograms;
 
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_mic_);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_camera_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
   WaitForBubbleToBeShown();
   histograms.ExpectTotalCount(
       "Permissions.Engagement.Denied.AudioAndVideoCapture", 0);
@@ -288,7 +288,7 @@
 TEST_F(ChromePermissionRequestManagerTest, UMAForIgnores) {
   base::HistogramTester histograms;
 
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request1_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
   WaitForBubbleToBeShown();
   histograms.ExpectTotalCount("Permissions.Engagement.Ignored.Geolocation", 0);
 
@@ -299,7 +299,7 @@
 
   permissions::MockPermissionRequest youtube_request(
       youtube, permissions::RequestType::kCameraStream);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &youtube_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &youtube_request);
   WaitForBubbleToBeShown();
 
   NavigateAndCommit(GURL(permissions::MockPermissionRequest::kDefaultOrigin));
@@ -341,7 +341,8 @@
     NavigateAndCommit(requesting_origin);
     permissions::MockPermissionRequest notification_request(
         requesting_origin, permissions::RequestType::kNotifications);
-    manager_->AddRequest(web_contents()->GetMainFrame(), &notification_request);
+    manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                         &notification_request);
     WaitForBubbleToBeShown();
     EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
     Deny();
@@ -362,7 +363,8 @@
     NavigateAndCommit(requesting_origin);
     permissions::MockPermissionRequest notification_request(
         requesting_origin, permissions::RequestType::kNotifications);
-    manager_->AddRequest(web_contents()->GetMainFrame(), &notification_request);
+    manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                         &notification_request);
     WaitForBubbleToBeShown();
     // Only show quiet UI after 3 consecutive denies of the permission prompt.
     EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
@@ -378,7 +380,8 @@
   NavigateAndCommit(requesting_origin);
   permissions::MockPermissionRequest notification_request(
       requesting_origin, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification_request);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   Accept();
@@ -420,7 +423,8 @@
     NavigateAndCommit(requesting_origin);
     permissions::MockPermissionRequest notification_request(
         requesting_origin, permissions::RequestType::kNotifications);
-    manager_->AddRequest(web_contents()->GetMainFrame(), &notification_request);
+    manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                         &notification_request);
     WaitForBubbleToBeShown();
     EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
     Deny();
@@ -436,7 +440,8 @@
   NavigateAndCommit(requesting_origin);
   permissions::MockPermissionRequest notification_request(
       requesting_origin, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification_request);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
@@ -461,7 +466,8 @@
   NavigateAndCommit(notification1);
   permissions::MockPermissionRequest notification1_request(
       notification1, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification1_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification1_request);
   WaitForBubbleToBeShown();
   Deny();
 
@@ -469,7 +475,8 @@
   NavigateAndCommit(notification2);
   permissions::MockPermissionRequest notification2_request(
       notification2, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification2_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification2_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -478,7 +485,8 @@
   NavigateAndCommit(notification3);
   permissions::MockPermissionRequest notification3_request(
       notification3, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification3_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification3_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Accept();
@@ -488,7 +496,8 @@
   NavigateAndCommit(notification4);
   permissions::MockPermissionRequest notification4_request(
       notification4, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification4_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification4_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -497,7 +506,8 @@
   NavigateAndCommit(notification5);
   permissions::MockPermissionRequest notification5_request(
       notification5, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification5_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification5_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -506,14 +516,14 @@
   // other permissions should not.
   GURL camera_url("http://www.camera.com/");
   NavigateAndCommit(camera_url);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_camera_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
 
   GURL microphone_url("http://www.microphone.com/");
   NavigateAndCommit(microphone_url);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_mic_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -522,7 +532,8 @@
   NavigateAndCommit(notification6);
   permissions::MockPermissionRequest notification6_request(
       notification6, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification6_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification6_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -535,7 +546,8 @@
       notification7, permissions::RequestType::kNotifications);
   // For the first quiet permission prompt, show a promo.
   EXPECT_TRUE(QuietNotificationPermissionUiState::ShouldShowPromo(profile()));
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification7_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification7_request);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
@@ -548,7 +560,8 @@
   NavigateAndCommit(notification8);
   permissions::MockPermissionRequest notification8_request(
       notification8, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification8_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification8_request);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
 
@@ -567,7 +580,8 @@
   NavigateAndCommit(notification9);
   permissions::MockPermissionRequest notification9_request(
       notification9, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification9_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification9_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -578,7 +592,8 @@
   NavigateAndCommit(notification10);
   permissions::MockPermissionRequest notification10_request(
       notification10, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification10_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification10_request);
   WaitForBubbleToBeShown();
   EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
   Deny();
@@ -588,7 +603,8 @@
   NavigateAndCommit(notification11);
   permissions::MockPermissionRequest notification11_request(
       notification11, permissions::RequestType::kNotifications);
-  manager_->AddRequest(web_contents()->GetMainFrame(), &notification11_request);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
+                       &notification11_request);
   WaitForBubbleToBeShown();
   Deny();
 
diff --git a/chrome/browser/permissions/chrome_permissions_client.cc b/chrome/browser/permissions/chrome_permissions_client.cc
index 88b4e16..894a742 100644
--- a/chrome/browser/permissions/chrome_permissions_client.cc
+++ b/chrome/browser/permissions/chrome_permissions_client.cc
@@ -272,7 +272,7 @@
     GetUkmSourceIdCallback callback) {
   if (web_contents) {
     ukm::SourceId source_id =
-        web_contents->GetMainFrame()->GetPageUkmSourceId();
+        web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
     std::move(callback).Run(source_id);
   } else {
     // We only record a permission change if the origin is in the user's
diff --git a/chrome/browser/permissions/permission_context_base_permissions_policy_unittest.cc b/chrome/browser/permissions/permission_context_base_permissions_policy_unittest.cc
index 5ffe078..d8258a8e 100644
--- a/chrome/browser/permissions/permission_context_base_permissions_policy_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_permissions_policy_unittest.cc
@@ -47,7 +47,7 @@
   static constexpr const char* kOrigin2 = "https://maps.google.com";
 
   content::RenderFrameHost* GetMainRFH(const char* origin) {
-    content::RenderFrameHost* result = web_contents()->GetMainFrame();
+    content::RenderFrameHost* result = web_contents()->GetPrimaryMainFrame();
     content::RenderFrameHostTester::For(result)
         ->InitializeRenderFrameIfNeeded();
     SimulateNavigation(&result, GURL(origin));
@@ -97,7 +97,7 @@
     return pcb
         ->GetPermissionStatus(
             rfh, rfh->GetLastCommittedURL(),
-            web_contents()->GetMainFrame()->GetLastCommittedURL())
+            web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL())
         .content_setting;
   }
 
diff --git a/chrome/browser/permissions/permission_delegation_browsertest.cc b/chrome/browser/permissions/permission_delegation_browsertest.cc
index 95b34cd..8499e91 100644
--- a/chrome/browser/permissions/permission_delegation_browsertest.cc
+++ b/chrome/browser/permissions/permission_delegation_browsertest.cc
@@ -91,7 +91,8 @@
       https_embedded_test_server()->GetURL("c.com", "/simple.html");
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
-  content::RenderFrameHost* main_frame = GetWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      GetWebContents()->GetPrimaryMainFrame();
 
   // Delegate permission to both frames.
   EXPECT_TRUE(content::ExecuteScript(
diff --git a/chrome/browser/permissions/permission_prompt_android_unittest.cc b/chrome/browser/permissions/permission_prompt_android_unittest.cc
index b0181da..b593dc9 100644
--- a/chrome/browser/permissions/permission_prompt_android_unittest.cc
+++ b/chrome/browser/permissions/permission_prompt_android_unittest.cc
@@ -50,8 +50,8 @@
   // Create a notification request. This causes an infobar to appear.
   permissions::MockPermissionRequest request(
       permissions::RequestType::kNotifications);
-  permission_request_manager()->AddRequest(web_contents()->GetMainFrame(),
-                                           &request);
+  permission_request_manager()->AddRequest(
+      web_contents()->GetPrimaryMainFrame(), &request);
 
   base::RunLoop().RunUntilIdle();
 
@@ -73,8 +73,8 @@
   // Create a notification request. This causes an infobar to appear.
   permissions::MockPermissionRequest request(
       permissions::RequestType::kNotifications);
-  permission_request_manager()->AddRequest(web_contents()->GetMainFrame(),
-                                           &request);
+  permission_request_manager()->AddRequest(
+      web_contents()->GetPrimaryMainFrame(), &request);
 
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc
index f4b161b..8dcf710f 100644
--- a/chrome/browser/permissions/permission_request_manager_browsertest.cc
+++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -215,7 +215,10 @@
   }
 
   content::RenderFrameHost* GetActiveMainFrame() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
  private:
@@ -397,7 +400,7 @@
 
   // Request geolocation in foreground tab, prompt should be shown.
   ExecuteScriptAndGetValue(
-      tab_strip_model->GetWebContentsAt(1)->GetMainFrame(),
+      tab_strip_model->GetWebContentsAt(1)->GetPrimaryMainFrame(),
       "navigator.geolocation.getCurrentPosition(function(){});");
   EXPECT_EQ(1, bubble_factory_1->show_count());
   EXPECT_FALSE(bubble_factory_0->is_visible());
@@ -414,8 +417,9 @@
 
   // Request notification in background tab. No prompt is shown until the tab
   // itself is activated.
-  ExecuteScriptAndGetValue(tab_strip_model->GetWebContentsAt(0)->GetMainFrame(),
-                           "Notification.requestPermission()");
+  ExecuteScriptAndGetValue(
+      tab_strip_model->GetWebContentsAt(0)->GetPrimaryMainFrame(),
+      "Notification.requestPermission()");
   EXPECT_FALSE(bubble_factory_0->is_visible());
   EXPECT_EQ(2, bubble_factory_1->show_count());
 
@@ -436,7 +440,7 @@
 
   // Request camera, prompt should be shown.
   ExecuteScriptAndGetValue(
-      browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame(),
+      browser()->tab_strip_model()->GetWebContentsAt(0)->GetPrimaryMainFrame(),
       "navigator.getUserMedia({video: true}, ()=>{}, ()=>{})");
   bubble_factory()->WaitForPermissionBubble();
   EXPECT_TRUE(bubble_factory()->is_visible());
@@ -451,7 +455,7 @@
 
   // Navigate background tab, prompt should be removed.
   ExecuteScriptAndGetValue(
-      browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame(),
+      browser()->tab_strip_model()->GetWebContentsAt(0)->GetPrimaryMainFrame(),
       "window.location = 'simple.html'");
   content::TestNavigationObserver observer(
       browser()->tab_strip_model()->GetWebContentsAt(0));
@@ -714,7 +718,7 @@
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
   permissions::MockPermissionRequest request_quiet(
       permissions::RequestType::kNotifications);
-  GetPermissionRequestManager()->AddRequest(web_contents->GetMainFrame(),
+  GetPermissionRequestManager()->AddRequest(web_contents->GetPrimaryMainFrame(),
                                             &request_quiet);
 
   bubble_factory()->WaitForPermissionBubble();
@@ -740,7 +744,7 @@
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
   permissions::MockPermissionRequest request_quiet(
       permissions::RequestType::kNotifications);
-  GetPermissionRequestManager()->AddRequest(web_contents->GetMainFrame(),
+  GetPermissionRequestManager()->AddRequest(web_contents->GetPrimaryMainFrame(),
                                             &request_quiet);
 
   bubble_factory()->WaitForPermissionBubble();
@@ -800,15 +804,15 @@
 
     permissions::MockPermissionRequest request_quiet(
         permissions::RequestType::kNotifications);
-    GetPermissionRequestManager()->AddRequest(web_contents->GetMainFrame(),
-                                              &request_quiet);
+    GetPermissionRequestManager()->AddRequest(
+        web_contents->GetPrimaryMainFrame(), &request_quiet);
 
     bubble_factory()->WaitForPermissionBubble();
     GetPermissionRequestManager()->Dismiss();
     base::RunLoop().RunUntilIdle();
 
     if (!test.expected_message) {
-      web_contents->GetMainFrame()->AddMessageToConsole(
+      web_contents->GetPrimaryMainFrame()->AddMessageToConsole(
           blink::mojom::ConsoleMessageLevel::kInfo,
           kCounterVerificationPattern);
     }
@@ -1167,8 +1171,8 @@
   GURL fenced_frame_url =
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_test_helper().CreateFencedFrame(web_contents->GetMainFrame(),
-                                                   fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   const char kQueryPermission[] = R"(
@@ -1217,8 +1221,8 @@
   // Load a fenced frame.
   GURL fenced_frame_url = https_server.GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_test_helper().CreateFencedFrame(web_contents->GetMainFrame(),
-                                                   fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   // The permission request is denied because it's from the fenced frame.
diff --git a/chrome/browser/permissions/permissions_browsertest.cc b/chrome/browser/permissions/permissions_browsertest.cc
index 88ea0557..5d3eced 100644
--- a/chrome/browser/permissions/permissions_browsertest.cc
+++ b/chrome/browser/permissions/permissions_browsertest.cc
@@ -42,7 +42,7 @@
 bool PermissionsBrowserTest::RunScriptReturnBool(const std::string& script) {
   bool result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
-      GetWebContents()->GetMainFrame(), script, &result));
+      GetWebContents()->GetPrimaryMainFrame(), script, &result));
   return result;
 }
 
diff --git a/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc b/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
index 6f4c565..3fcc1d0 100644
--- a/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
+++ b/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
@@ -165,7 +165,7 @@
   EXPECT_NE(popup, browser);
   content::WebContents* popup_contents =
       popup->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetMainFrame()));
+  EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetPrimaryMainFrame()));
   WaitForLoadStop(popup_contents);
   return popup_contents;
 }
@@ -283,7 +283,7 @@
                       const std::string& request_permission_script,
                       const std::string& check_permission_script) {
   content::RenderFrameHost* opener_rfh =
-      opener_or_embedder_contents->GetMainFrame();
+      opener_or_embedder_contents->GetPrimaryMainFrame();
   ASSERT_FALSE(
       content::EvalJs(opener_rfh, check_permission_script).value.GetBool());
   ASSERT_FALSE(
@@ -334,7 +334,7 @@
     const std::string& request_permission_script,
     const std::string& check_permission_script) {
   content::RenderFrameHost* embedder_main_rfh =
-      embedder_contents->GetMainFrame();
+      embedder_contents->GetPrimaryMainFrame();
   ASSERT_FALSE(content::EvalJs(embedder_main_rfh, check_permission_script)
                    .value.GetBool());
   ASSERT_FALSE(
@@ -385,8 +385,8 @@
 // getUserMedia requires focus. It should be verified only on a popup window.
 void VerifyPopupWindowGetUserMedia(content::WebContents* opener_contents,
                                    content::WebContents* popup_contents) {
-  content::RenderFrameHost* opener_rfh = opener_contents->GetMainFrame();
-  content::RenderFrameHost* popup_rfh = popup_contents->GetMainFrame();
+  content::RenderFrameHost* opener_rfh = opener_contents->GetPrimaryMainFrame();
+  content::RenderFrameHost* popup_rfh = popup_contents->GetPrimaryMainFrame();
 
   ASSERT_FALSE(content::EvalJs(opener_rfh, kCheckCamera).value.GetBool());
   ASSERT_FALSE(content::EvalJs(popup_rfh, kCheckCamera).value.GetBool());
@@ -419,7 +419,8 @@
     content::WebContents* portal_contents,
     const std::string& request_permission_script,
     const std::string& check_permission_script) {
-  content::RenderFrameHost* portal_main_rfh = portal_contents->GetMainFrame();
+  content::RenderFrameHost* portal_main_rfh =
+      portal_contents->GetPrimaryMainFrame();
   ASSERT_FALSE(content::EvalJs(portal_main_rfh, check_permission_script)
                    .value.GetBool());
 
@@ -629,7 +630,7 @@
   ASSERT_TRUE(popup_contents);
 
   VerifyPermissionsExceptGetUserMedia(opener_contents,
-                                      popup_contents->GetMainFrame());
+                                      popup_contents->GetPrimaryMainFrame());
   VerifyPopupWindowGetUserMedia(opener_contents, popup_contents);
 }
 
@@ -692,8 +693,8 @@
   ASSERT_TRUE(blob_popup_contents);
   EXPECT_TRUE(blob_popup_contents->GetLastCommittedURL().SchemeIsBlob());
 
-  VerifyPermissionsExceptGetUserMedia(opener_contents,
-                                      blob_popup_contents->GetMainFrame());
+  VerifyPermissionsExceptGetUserMedia(
+      opener_contents, blob_popup_contents->GetPrimaryMainFrame());
   VerifyPopupWindowGetUserMedia(opener_contents, blob_popup_contents);
 }
 
@@ -1144,7 +1145,8 @@
     content::WebContents* embedder_contents = GetWebContents();
 
     EXPECT_TRUE(content::NavigateToURL(embedder_contents, url));
-    content::RenderFrameHost* main_rfh = embedder_contents->GetMainFrame();
+    content::RenderFrameHost* main_rfh =
+        embedder_contents->GetPrimaryMainFrame();
     EXPECT_EQ(origin, main_rfh->GetLastCommittedOrigin());
 
     // By default permissions are not allowed.
@@ -1427,8 +1429,8 @@
   GURL fenced_frame_url =
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_test_helper().CreateFencedFrame(web_contents->GetMainFrame(),
-                                                   fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(
+          web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   VerifyPermissionsDeniedForFencedFrame(web_contents, fenced_frame_host);
@@ -1468,7 +1470,7 @@
 
   // `contents` is in a default state.
   EXPECT_FALSE(contents->IsPortal());
-  VerifyPermissionsAllowed(contents->GetMainFrame());
+  VerifyPermissionsAllowed(contents->GetPrimaryMainFrame());
 
   EXPECT_EQ(true, content::EvalJs(contents, "loadPromise"));
   std::vector<content::WebContents*> inner_web_contents =
@@ -1543,8 +1545,10 @@
   ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
 
   EXPECT_FALSE(
-      GetActiveWebContents()->GetMainFrame()->IsInactiveAndDisallowActivation(
-          content::DisallowActivationReasonId::kRequestPermission));
+      GetActiveWebContents()
+          ->GetPrimaryMainFrame()
+          ->IsInactiveAndDisallowActivation(
+              content::DisallowActivationReasonId::kRequestPermission));
 
   // Start a prerender.
   GURL prerender_url =
@@ -1559,8 +1563,10 @@
 
   // The main frame of an outer document is not a prerenderer.
   EXPECT_FALSE(
-      GetActiveWebContents()->GetMainFrame()->IsInactiveAndDisallowActivation(
-          content::DisallowActivationReasonId::kRequestPermission));
+      GetActiveWebContents()
+          ->GetPrimaryMainFrame()
+          ->IsInactiveAndDisallowActivation(
+              content::DisallowActivationReasonId::kRequestPermission));
 
   // The main frame of a newly created frame tree is a prerenderer. It is
   // inactive, all permission requests should be automatically denied.
@@ -1635,7 +1641,7 @@
 
   // 1) Navigate to A.
   EXPECT_TRUE(content::NavigateToURL(embedder_contents, url_a));
-  content::RenderFrameHost* rfh_a = embedder_contents->GetMainFrame();
+  content::RenderFrameHost* rfh_a = embedder_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(rfh_a);
   EXPECT_EQ(origin_a, rfh_a->GetLastCommittedOrigin());
   // Currently active RFH is not `kInBackForwardCache`.
@@ -1645,7 +1651,7 @@
 
   // 2) Navigate to B.
   EXPECT_TRUE(content::NavigateToURL(embedder_contents, url_b));
-  content::RenderFrameHost* rfh_b = embedder_contents->GetMainFrame();
+  content::RenderFrameHost* rfh_b = embedder_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(rfh_b);
   EXPECT_EQ(origin_b, rfh_b->GetLastCommittedOrigin());
   // Currently active RFH is not `kInBackForwardCache`.
@@ -1661,10 +1667,10 @@
 
   // 3) Verify that `HistoryGoBack` restores previously cached `rfh_a` and does
   // not create a new one.
-  EXPECT_NE(rfh_a, embedder_contents->GetMainFrame());
+  EXPECT_NE(rfh_a, embedder_contents->GetPrimaryMainFrame());
   // After `HistoryGoBack` `rfh_a` should be moved back from the BFCache.
   ASSERT_TRUE(HistoryGoBack(embedder_contents));
-  EXPECT_EQ(rfh_a, embedder_contents->GetMainFrame());
+  EXPECT_EQ(rfh_a, embedder_contents->GetPrimaryMainFrame());
   EXPECT_EQ(rfh_a->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kActive);
 
@@ -1688,11 +1694,11 @@
   bubble_factory->set_response_type(
       permissions::PermissionRequestManager::AutoResponseType::ACCEPT_ALL);
 
-  EXPECT_FALSE(
-      content::EvalJs(embedder_contents->GetMainFrame(), kCheckGeolocation)
-          .value.GetBool());
+  EXPECT_FALSE(content::EvalJs(embedder_contents->GetPrimaryMainFrame(),
+                               kCheckGeolocation)
+                   .value.GetBool());
 
-  EXPECT_EQ("granted", content::EvalJs(embedder_contents->GetMainFrame(),
+  EXPECT_EQ("granted", content::EvalJs(embedder_contents->GetPrimaryMainFrame(),
                                        kRequestGeolocation));
   EXPECT_EQ(1, bubble_factory->TotalRequestCount());
 
@@ -1712,7 +1718,7 @@
 
   // 5) Go back to a.test and verify that it has no permissions.
   ASSERT_TRUE(HistoryGoBack(embedder_contents));
-  content::RenderFrameHost* rfh_a_2 = embedder_contents->GetMainFrame();
+  content::RenderFrameHost* rfh_a_2 = embedder_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(rfh_a_2);
   EXPECT_EQ(origin_a, rfh_a_2->GetLastCommittedOrigin());
   // Verify that `a.test` has no granted Geolocation permission despite it being
@@ -1889,7 +1895,7 @@
   GURL url = GetTestServerInsecureUrl("/extensions/test_file.html?succeed");
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_rfh = web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(main_rfh);
 
   content::RenderFrameHost* iframe_with_embedded_extension =
@@ -1983,7 +1989,7 @@
   GURL url = GetTestServerInsecureUrl("/extensions/test_file.html?succeed");
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_rfh = web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(main_rfh);
 
   content::RenderFrameHost* iframe_with_embedded_extension =
@@ -2057,7 +2063,7 @@
   GURL url = embedded_test_server()->GetURL("/extensions/test_file.html");
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_rfh = web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(main_rfh);
 
   // Allow permissions on the main frame, so they became available for an
diff --git a/chrome/browser/permissions/prediction_service_browsertest.cc b/chrome/browser/permissions/prediction_service_browsertest.cc
index 847cc6e..99dbb5f 100644
--- a/chrome/browser/permissions/prediction_service_browsertest.cc
+++ b/chrome/browser/permissions/prediction_service_browsertest.cc
@@ -64,7 +64,10 @@
   }
 
   content::RenderFrameHost* GetActiveMainFrame() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
   PermissionRequestManager* GetPermissionRequestManager() {
diff --git a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
index 82196a2..880889d7 100644
--- a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
@@ -1013,7 +1013,7 @@
   ASSERT_EQ(2u, render_frame_hosts.size());
 
   content::RenderFrameHost* iframe =
-      render_frame_hosts[0] == active_web_contents->GetMainFrame()
+      render_frame_hosts[0] == active_web_contents->GetPrimaryMainFrame()
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
@@ -1081,7 +1081,7 @@
   ASSERT_EQ(2u, render_frame_hosts.size());
 
   content::RenderFrameHost* iframe =
-      render_frame_hosts[0] == active_web_contents->GetMainFrame()
+      render_frame_hosts[0] == active_web_contents->GetPrimaryMainFrame()
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
@@ -1115,7 +1115,7 @@
   ASSERT_EQ(2u, render_frame_hosts.size());
 
   content::RenderFrameHost* iframe =
-      render_frame_hosts[0] == active_web_contents->GetMainFrame()
+      render_frame_hosts[0] == active_web_contents->GetPrimaryMainFrame()
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
@@ -1337,7 +1337,7 @@
   ASSERT_EQ(2u, render_frame_hosts.size());
 
   content::RenderFrameHost* iframe =
-      render_frame_hosts[0] == active_web_contents->GetMainFrame()
+      render_frame_hosts[0] == active_web_contents->GetPrimaryMainFrame()
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
@@ -1649,7 +1649,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          active_web_contents->GetMainFrame(), fenced_frame_url);
+          active_web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
 }
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc
index 480a53d..5046ec4f 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter.cc
+++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -97,23 +97,24 @@
 
   // Authorize all plugins is intended for the granting access to only
   // the currently active page, so we iterate on the main frame.
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating([](content::RenderFrameHost* render_frame_host) {
         ChromePluginServiceFilter::GetInstance()->AuthorizePlugin(
             render_frame_host->GetProcess()->GetID(), base::FilePath());
       }));
 
   if (load_blocked) {
-    web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-        [](const std::string& identifier,
-           content::RenderFrameHost* render_frame_host) {
-          mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame>
-              chrome_render_frame;
-          render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
-              &chrome_render_frame);
-          chrome_render_frame->LoadBlockedPlugins(identifier);
-        },
-        identifier));
+    web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+        base::BindRepeating(
+            [](const std::string& identifier,
+               content::RenderFrameHost* render_frame_host) {
+              mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame>
+                  chrome_render_frame;
+              render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+                  &chrome_render_frame);
+              chrome_render_frame->LoadBlockedPlugins(identifier);
+            },
+            identifier));
   }
 }
 
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter_unittest.cc b/chrome/browser/plugins/chrome_plugin_service_filter_unittest.cc
index 28d780b..d2da0d3 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter_unittest.cc
+++ b/chrome/browser/plugins/chrome_plugin_service_filter_unittest.cc
@@ -36,7 +36,7 @@
   }
 
   int main_frame_process_id() {
-    return web_contents()->GetMainFrame()->GetProcess()->GetID();
+    return web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
   }
 
   raw_ptr<ChromePluginServiceFilter> filter_ = nullptr;
diff --git a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
index 161733e..79745df 100644
--- a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
+++ b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
@@ -60,7 +60,7 @@
 bool IsPDFPluginEnabled(content::NavigationHandle* navigation_handle,
                         bool* is_stale) {
   content::WebContents* web_contents = navigation_handle->GetWebContents();
-  int process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+  int process_id = web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
 
   content::WebPluginInfo plugin_info;
   return content::PluginService::GetInstance()->GetPluginInfo(
diff --git a/chrome/browser/plugins/pdf_iframe_navigation_throttle_browsertest.cc b/chrome/browser/plugins/pdf_iframe_navigation_throttle_browsertest.cc
index 5ce635b1..479672f 100644
--- a/chrome/browser/plugins/pdf_iframe_navigation_throttle_browsertest.cc
+++ b/chrome/browser/plugins/pdf_iframe_navigation_throttle_browsertest.cc
@@ -123,7 +123,7 @@
   // the prerender.
   {
     PrerenderHostObserver prerender_observer(*web_contents(), kPrerenderUrl);
-    ASSERT_TRUE(ExecJs(web_contents()->GetMainFrame(),
+    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                        JsReplace("location = $1", kPrerenderUrl)));
     prerender_observer.WaitForActivation();
   }
@@ -137,7 +137,7 @@
     EXPECT_TRUE(pdf_navigation.was_successful());
 
     content::RenderFrameHost* child_frame =
-        ChildFrameAt(web_contents()->GetMainFrame(), 0);
+        ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
     ASSERT_TRUE(child_frame);
     EXPECT_EQ(child_frame->GetLastCommittedURL(), kFallbackPdfUrl);
   }
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc
index 0560773..6c3fdf8 100644
--- a/chrome/browser/policy/extension_policy_browsertest.cc
+++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -200,11 +200,15 @@
   click_event.button = blink::WebMouseEvent::Button::kLeft;
   click_event.click_count = 1;
   click_event.SetPositionInWidget(x, y);
-  contents->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      click_event);
+  contents->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(click_event);
   click_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  contents->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      click_event);
+  contents->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(click_event);
 }
 
 class ExtensionPolicyTest : public ExtensionPolicyTestBase {
diff --git a/chrome/browser/policy/test/autoplay_policy_browsertest.cc b/chrome/browser/policy/test/autoplay_policy_browsertest.cc
index d107ba3..3095e64 100644
--- a/chrome/browser/policy/test/autoplay_policy_browsertest.cc
+++ b/chrome/browser/policy/test/autoplay_policy_browsertest.cc
@@ -69,12 +69,12 @@
     return browser()->tab_strip_model()->GetActiveWebContents();
   }
 
-  content::RenderFrameHost* GetMainFrame() {
-    return GetWebContents()->GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame() {
+    return GetWebContents()->GetPrimaryMainFrame();
   }
 
   content::RenderFrameHost* GetChildFrame() {
-    return ChildFrameAt(GetMainFrame(), 0);
+    return ChildFrameAt(GetPrimaryMainFrame(), 0);
   }
 
  private:
@@ -86,7 +86,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Update policy to allow autoplay.
@@ -96,7 +96,7 @@
 
   // Check that autoplay was allowed by policy.
   NavigateToTestPage();
-  EXPECT_TRUE(TryAutoplay(GetMainFrame()));
+  EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_TRUE(TryAutoplay(GetChildFrame()));
 }
 
@@ -110,7 +110,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with our origin.
@@ -124,7 +124,7 @@
 
   // Check that autoplay was allowed by policy.
   NavigateToTestPage();
-  EXPECT_TRUE(TryAutoplay(GetMainFrame()));
+  EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_TRUE(TryAutoplay(GetChildFrame()));
 }
 
@@ -132,7 +132,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with our origin.
@@ -146,7 +146,7 @@
 
   // Check that autoplay was allowed by policy.
   NavigateToTestPage();
-  EXPECT_TRUE(TryAutoplay(GetMainFrame()));
+  EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_TRUE(TryAutoplay(GetChildFrame()));
 }
 
@@ -154,7 +154,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with a random origin.
@@ -168,7 +168,7 @@
 
   // Check that autoplay was not allowed.
   NavigateToTestPage();
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 }
 
@@ -182,7 +182,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Update policy to forbid autoplay.
@@ -192,7 +192,7 @@
 
   // Check that autoplay was not allowed by policy.
   NavigateToTestPage();
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with a random origin.
@@ -205,7 +205,7 @@
 
   // Check that autoplay was not allowed.
   NavigateToTestPage();
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 }
 
@@ -219,7 +219,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Update policy to forbid autoplay.
@@ -229,7 +229,7 @@
 
   // Check that autoplay was not allowed by policy.
   NavigateToTestPage();
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with our test origin.
@@ -242,7 +242,7 @@
 
   // Check that autoplay was allowed by policy.
   NavigateToTestPage();
-  EXPECT_TRUE(TryAutoplay(GetMainFrame()));
+  EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_TRUE(TryAutoplay(GetChildFrame()));
 }
 
@@ -252,7 +252,7 @@
   NavigateToTestPage();
 
   // Check that autoplay was not allowed.
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Update policy to forbid autoplay.
@@ -262,7 +262,7 @@
 
   // Check that autoplay was not allowed by policy.
   NavigateToTestPage();
-  EXPECT_FALSE(TryAutoplay(GetMainFrame()));
+  EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_FALSE(TryAutoplay(GetChildFrame()));
 
   // Create a test allowlist with our test origin.
@@ -275,7 +275,7 @@
 
   // Check that autoplay was allowed by policy.
   NavigateToTestPage();
-  EXPECT_TRUE(TryAutoplay(GetMainFrame()));
+  EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
   EXPECT_TRUE(TryAutoplay(GetChildFrame()));
 }
 
@@ -294,12 +294,12 @@
     // Append a cross origin fenced frame into the primary main frame.
     content::RenderFrameHost* fenced_frame_host =
         fenced_frame_helper_.CreateFencedFrame(
-            GetMainFrame(),
+            GetPrimaryMainFrame(),
             embedded_test_server2()->GetURL(kUnifiedAutoplayTestPageURL));
     ASSERT_NE(nullptr, fenced_frame_host);
 
     // Check that autoplay works as |expected_result|.
-    EXPECT_EQ(TryAutoplay(GetMainFrame()), expected_result);
+    EXPECT_EQ(TryAutoplay(GetPrimaryMainFrame()), expected_result);
     EXPECT_EQ(TryAutoplay(fenced_frame_host), expected_result);
   }
 
diff --git a/chrome/browser/policy/test/certificate_transparency_policy_browsertest.cc b/chrome/browser/policy/test/certificate_transparency_policy_browsertest.cc
index 1354fda..c1276ee 100644
--- a/chrome/browser/policy/test/certificate_transparency_policy_browsertest.cc
+++ b/chrome/browser/policy/test/certificate_transparency_policy_browsertest.cc
@@ -78,7 +78,7 @@
   ASSERT_TRUE(IsShowingInterstitial(tab));
 
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
   EXPECT_NE(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle());
 
   // Now exempt the URL from being blocked by setting policy.
@@ -137,7 +137,7 @@
   ASSERT_TRUE(helper);
   ASSERT_TRUE(
       helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting());
-  main_frame = web_contents->GetMainFrame();
+  main_frame = web_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(content::WaitForRenderFrameReady(main_frame));
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
       main_frame, "proceed-link"));
diff --git a/chrome/browser/policy/test/content_settings_policy_browsertest.cc b/chrome/browser/policy/test/content_settings_policy_browsertest.cc
index d8a459d..d95ea47 100644
--- a/chrome/browser/policy/test/content_settings_policy_browsertest.cc
+++ b/chrome/browser/policy/test/content_settings_policy_browsertest.cc
@@ -49,7 +49,7 @@
 
 bool IsJavascriptEnabled(content::WebContents* contents) {
   base::Value value =
-      content::ExecuteScriptAndGetValue(contents->GetMainFrame(), "123");
+      content::ExecuteScriptAndGetValue(contents->GetPrimaryMainFrame(), "123");
   return value.is_int() && value.GetInt() == 123;
 }
 
@@ -194,7 +194,7 @@
   content::WebContents* const web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_THAT(
-      web_contents->GetMainFrame()->GetLastCommittedOrigin().Serialize(),
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().Serialize(),
       testing::StartsWith("http://localhost:"));
 
   // Set the policy to block Web Bluetooth.
@@ -358,7 +358,8 @@
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(content::WaitForLoadStop(contents));
-  ASSERT_TRUE(content::WaitForRenderFrameReady(contents->GetMainFrame()));
+  ASSERT_TRUE(
+      content::WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
 
   content::RenderFrameSubmissionObserver frame_observer(contents);
   if (IsScrollToTextFragmentEnabled()) {
@@ -367,7 +368,7 @@
     // Force a frame - if it were going to happen, the scroll would complete
     // before this forced frame makes its way through the pipeline.
     content::RunUntilInputProcessed(
-        contents->GetMainFrame()->GetView()->GetRenderWidgetHost());
+        contents->GetPrimaryMainFrame()->GetView()->GetRenderWidgetHost());
   }
   EXPECT_EQ(IsScrollToTextFragmentEnabled(),
             !frame_observer.LastRenderFrameMetadata().is_scroll_offset_at_top);
@@ -440,7 +441,7 @@
   content::WebContents* const web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_THAT(
-      web_contents->GetMainFrame()->GetLastCommittedOrigin().Serialize(),
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().Serialize(),
       testing::StartsWith("http://localhost:"));
 
   // Set the policy to block Sensors.
diff --git a/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc b/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc
index 8557c6f8..9a2e127 100644
--- a/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc
+++ b/chrome/browser/policy/test/isolated_apps_developer_mode_allowed_browsertest.cc
@@ -89,7 +89,7 @@
       https_server()->GetURL(kIsolatedAppHost, "/policy/direct_sockets.html")));
 
   const bool enabled = std::get<1>(GetParam());
-  ASSERT_EQ(enabled, EvalJs(app_contents->GetMainFrame(), "mockTcp()"));
+  ASSERT_EQ(enabled, EvalJs(app_contents->GetPrimaryMainFrame(), "mockTcp()"));
 }
 
 IN_PROC_BROWSER_TEST_P(IsolatedAppsDeveloperModeAllowedPolicyTest, MockUdp) {
@@ -103,7 +103,7 @@
       https_server()->GetURL(kIsolatedAppHost, "/policy/direct_sockets.html")));
 
   const bool enabled = std::get<1>(GetParam());
-  ASSERT_EQ(enabled, EvalJs(app_contents->GetMainFrame(), "mockUdp()"));
+  ASSERT_EQ(enabled, EvalJs(app_contents->GetPrimaryMainFrame(), "mockUdp()"));
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/policy/test/media_stream_policy_browsertest.cc b/chrome/browser/policy/test/media_stream_policy_browsertest.cc
index eb49c8bc..78b2665 100644
--- a/chrome/browser/policy/test/media_stream_policy_browsertest.cc
+++ b/chrome/browser/policy/test/media_stream_policy_browsertest.cc
@@ -65,9 +65,10 @@
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     EXPECT_EQ(request_url_,
-              web_contents->GetMainFrame()->GetLastCommittedURL());
-    int render_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
-    int render_frame_id = web_contents->GetMainFrame()->GetRoutingID();
+              web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
+    int render_process_id =
+        web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
+    int render_frame_id = web_contents->GetPrimaryMainFrame()->GetRoutingID();
     return content::MediaStreamRequest(
         render_process_id, render_frame_id, 0,
         request_url_.DeprecatedGetOriginAsURL(), false,
diff --git a/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc b/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
index 45b04db..6ac3c0e 100644
--- a/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
+++ b/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
@@ -50,8 +50,8 @@
                      "protection message.";
   }
   int result = 0;
-  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(tab->GetMainFrame(), command,
-                                                  &result));
+  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(tab->GetPrimaryMainFrame(),
+                                                  command, &result));
   return result;
 }
 
diff --git a/chrome/browser/policy/test/ssl_error_overriding_allowed_policy_browsertest.cc b/chrome/browser/policy/test/ssl_error_overriding_allowed_policy_browsertest.cc
index e4db8d6..4d75fe2 100644
--- a/chrome/browser/policy/test/ssl_error_overriding_allowed_policy_browsertest.cc
+++ b/chrome/browser/policy/test/ssl_error_overriding_allowed_policy_browsertest.cc
@@ -63,7 +63,7 @@
 
   // The interstitial should display the proceed link.
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 }
 
 // Test that when SSL error overriding is allowed, the origin list is ignored
@@ -109,7 +109,7 @@
 
   // The interstitial should display the proceed link.
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 }
 
 // Test that when SSL error overriding is disabled, the proceed link does not
@@ -144,7 +144,7 @@
 
   // The interstitial should not display the proceed link.
   EXPECT_FALSE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 
   // The interstitial should not proceed, even if the command is sent in
   // some other way (e.g., via the keyboard shortcut).
@@ -200,7 +200,7 @@
 
   // The interstitial should not display the proceed link.
   EXPECT_FALSE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 
   // The interstitial should not proceed, even if the command is sent in
   // some other way (e.g., via the keyboard shortcut).
@@ -254,7 +254,7 @@
 
   // The interstitial should not display the proceed link.
   EXPECT_FALSE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 
   // The interstitial should not proceed, even if the command is sent in
   // some other way (e.g., via the keyboard shortcut).
@@ -305,7 +305,7 @@
 
   // The interstitial should not display the proceed link.
   EXPECT_FALSE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 
   // The interstitial should not proceed, even if the command is sent in
   // some other way (e.g., via the keyboard shortcut).
@@ -362,7 +362,7 @@
 
   // The interstitial should display the proceed link.
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), "proceed-link"));
+      tab->GetPrimaryMainFrame(), "proceed-link"));
 }
 
 }  // namespace policy
diff --git a/chrome/browser/policy/test/web_rtc_event_log_collection_allowed_policy_browsertest.cc b/chrome/browser/policy/test/web_rtc_event_log_collection_allowed_policy_browsertest.cc
index 60727c6..a795ff98 100644
--- a/chrome/browser/policy/test/web_rtc_event_log_collection_allowed_policy_browsertest.cc
+++ b/chrome/browser/policy/test/web_rtc_event_log_collection_allowed_policy_browsertest.cc
@@ -99,7 +99,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::GlobalRenderFrameHostId frame_id =
-      web_contents->GetMainFrame()->GetGlobalId();
+      web_contents->GetPrimaryMainFrame()->GetGlobalId();
 
   constexpr int kLid = 123;
   const std::string kSessionId = "id";
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc
index 3523d1d..b8e535a7 100644
--- a/chrome/browser/predictors/loading_predictor_browsertest.cc
+++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -1079,7 +1079,7 @@
     EXPECT_EQ(200, EvalJs(browser()
                               ->tab_strip_model()
                               ->GetActiveWebContents()
-                              ->GetMainFrame(),
+                              ->GetPrimaryMainFrame(),
                           fetch_resource));
 
     EXPECT_EQ(2u, connection_tracker()->GetAcceptedSocketCount());
@@ -1123,11 +1123,11 @@
       "  var resp = (await fetch('%s'));"
       "  return resp.status; })();",
       embedded_test_server()->GetURL("/echo").spec().c_str());
-  EXPECT_EQ(
-      200,
-      EvalJs(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          fetch_resource));
+  EXPECT_EQ(200, EvalJs(browser()
+                            ->tab_strip_model()
+                            ->GetActiveWebContents()
+                            ->GetPrimaryMainFrame(),
+                        fetch_resource));
 
   EXPECT_EQ(1u, connection_tracker()->GetAcceptedSocketCount());
   EXPECT_EQ(1u, connection_tracker()->GetReadSocketCount());
@@ -1225,7 +1225,7 @@
       "link.href = '%s';"
       "document.head.appendChild(link);",
       preconnect_url.spec().c_str());
-  content::ExecuteScriptAsync(tab1->GetMainFrame(), start_preconnect);
+  content::ExecuteScriptAsync(tab1->GetPrimaryMainFrame(), start_preconnect);
   connection_tracker()->WaitForAcceptedConnections(1u);
   EXPECT_EQ(1u, connection_tracker()->GetAcceptedSocketCount());
   EXPECT_EQ(0u, connection_tracker()->GetReadSocketCount());
@@ -1238,7 +1238,7 @@
       "  return resp.status; })();",
       preconnect_url.spec().c_str());
   // Fetch a resource from the test server from tab 2, without CORS.
-  EXPECT_EQ(0, EvalJs(tab2->GetMainFrame(), fetch_resource));
+  EXPECT_EQ(0, EvalJs(tab2->GetPrimaryMainFrame(), fetch_resource));
   if (GetParam() == NetworkIsolationKeyMode::kDisabled) {
     // When not using NetworkIsolationKeys, the preconnected socket from a tab
     // at one site is usable by a request from another site.
@@ -1251,7 +1251,7 @@
   }
 
   // Now try fetching a resource from tab 1.
-  EXPECT_EQ(0, EvalJs(tab1->GetMainFrame(), fetch_resource));
+  EXPECT_EQ(0, EvalJs(tab1->GetPrimaryMainFrame(), fetch_resource));
   // If the preconnected socket was not used before, it should now be used. If
   // it was used before, a new socket will be used.
   EXPECT_EQ(2u, connection_tracker()->GetAcceptedSocketCount());
@@ -1272,7 +1272,7 @@
                      kHost1, GetPathWithPortReplacement(
                                  "/predictors/two_iframes.html",
                                  preconnecting_test_server()->port()))));
-  content::RenderFrameHost* main_frame = tab1->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab1->GetPrimaryMainFrame();
   ASSERT_EQ(kHost1, main_frame->GetLastCommittedOrigin().host());
   content::RenderFrameHost* iframe_1 = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(iframe_1);
@@ -1310,7 +1310,7 @@
       preconnect_url.spec().c_str());
 
   // Fetch a resource from the test server from tab 2 iframe, without CORS.
-  EXPECT_EQ(0, EvalJs(tab2->GetMainFrame(), fetch_resource));
+  EXPECT_EQ(0, EvalJs(tab2->GetPrimaryMainFrame(), fetch_resource));
   if (GetParam() == NetworkIsolationKeyMode::kDisabled) {
     // When not using NetworkIsolationKeys, the preconnected socket from the
     // iframe from the first tab can be used.
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper.cc b/chrome/browser/predictors/loading_predictor_tab_helper.cc
index 6ebb6bc..fb5872c 100644
--- a/chrome/browser/predictors/loading_predictor_tab_helper.cc
+++ b/chrome/browser/predictors/loading_predictor_tab_helper.cc
@@ -402,7 +402,8 @@
   if (!predictor_)
     return;
 
-  auto* page_data = PageData::GetForDocument(*web_contents()->GetMainFrame());
+  auto* page_data =
+      PageData::GetForDocument(*web_contents()->GetPrimaryMainFrame());
   if (!page_data)
     return;
 
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc
index b71423d9..2e7b40f4 100644
--- a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc
+++ b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc
@@ -149,7 +149,7 @@
   NavigateAndCommitInFrame(url, main_rfh());
 
   EXPECT_EQ(ukm_source_id,
-            web_contents()->GetMainFrame()->GetPageUkmSourceId());
+            web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId());
   GURL gurl(url);
   EXPECT_EQ(gurl, main_frame_url);
   EXPECT_EQ(gurl, old_main_frame_url);
@@ -202,7 +202,7 @@
       RecordFinishNavigation(_, main_frame_url, expected_main_frame_url, _));
   navigation->Commit();
 
-  EXPECT_EQ(web_contents()->GetMainFrame()->GetPageUkmSourceId(),
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
             ukm_source_id);
 }
 
@@ -241,7 +241,7 @@
 
   EXPECT_EQ(ukm_source_id,
 
-            web_contents()->GetMainFrame()->GetPageUkmSourceId());
+            web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId());
 }
 
 // Tests that a same document navigation is not recorded.
diff --git a/chrome/browser/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
index 1e1e95f..2918b49 100644
--- a/chrome/browser/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
+++ b/chrome/browser/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
@@ -393,7 +393,8 @@
                          const GURL& ping_url,
                          bool new_web_contents) const {
     content::WebContents* web_contents = GetActiveWebContents();
-    content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+    content::RenderFrameHost* render_frame_host =
+        web_contents->GetPrimaryMainFrame();
     // Extra arguments in JS are ignored.
     std::string javascript =
         base::StringPrintf("%s('%s', '%s')", javascript_function_name.c_str(),
@@ -1851,9 +1852,11 @@
   const GURL fenced_frame_url =
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      fenced_frame_test_helper().CreateFencedFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          fenced_frame_url);
+      fenced_frame_test_helper().CreateFencedFrame(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                   fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
   // NoStatePrefetchManager should not record the navigation on fenced frame
   // navigation.
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
index be148e3..445a7ba 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
@@ -1452,7 +1452,7 @@
   tab_helper_observer.SetOnPrefetchSuccessfulClosure(run_loop.QuitClosure());
 
   ukm::SourceId srp_source_id =
-      GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   base::HistogramTester histogram_tester;
 
@@ -2199,7 +2199,7 @@
       blink::StorageKey(url::Origin::Create(starting_page))));
 
   ukm::SourceId srp_source_id =
-      GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   base::RunLoop run_loop;
   TestTabHelperObserver tab_helper_observer(
@@ -2281,7 +2281,7 @@
                                  "cookietype=ChocolateChip"));
 
   ukm::SourceId srp_source_id =
-      GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   base::RunLoop run_loop;
   TestTabHelperObserver tab_helper_observer(
@@ -3613,7 +3613,7 @@
   tab_helper_observer.SetOnNSPFinishedClosure(nsp_run_loop.QuitClosure());
 
   ukm::SourceId srp_source_id =
-      GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   GURL doc_url("https://www.google.com/search?q=test");
   MakeNavigationPrediction(doc_url, {eligible_link});
@@ -3824,7 +3824,7 @@
   tab_helper_observer.SetOnNSPFinishedClosure(nsp_run_loop.QuitClosure());
 
   ukm::SourceId srp_source_id =
-      GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   GURL doc_url("https://www.google.com/search?q=test");
   MakeNavigationPrediction(doc_url, {eligible_link});
@@ -4482,7 +4482,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), fenced_frame_url);
+          GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
   ASSERT_EQ(fenced_frame_url, fenced_frame_host->GetLastCommittedURL());
 
@@ -4827,7 +4827,7 @@
 
   GURL starting_page = GetOriginServerURL("/search/q=blah");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), starting_page));
-  content::OverrideLastCommittedOrigin(GetWebContents()->GetMainFrame(),
+  content::OverrideLastCommittedOrigin(GetWebContents()->GetPrimaryMainFrame(),
                                        url::Origin::Create(starting_page));
   WaitForUpdatedCustomProxyConfig();
 
@@ -4898,7 +4898,7 @@
 
   GURL localhost_url = GetLocalhostURL("/search/q=blah");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), localhost_url));
-  content::OverrideLastCommittedOrigin(GetWebContents()->GetMainFrame(),
+  content::OverrideLastCommittedOrigin(GetWebContents()->GetPrimaryMainFrame(),
                                        url::Origin::Create(localhost_url));
   WaitForUpdatedCustomProxyConfig();
 
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_subresource_manager.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_subresource_manager.cc
index be0448d..3272d2ad 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_subresource_manager.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_subresource_manager.cc
@@ -89,7 +89,7 @@
   }
 
   int prerender_process_id =
-      web_contents->GetMainFrame()->GetProcess()->GetID();
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
   if (prerender_process_id != render_process_id) {
     return false;
   }
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc
index 46c2380..2edc3f8 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc
@@ -1364,7 +1364,7 @@
     page_->prefetch_metrics_collector_ =
         base::MakeRefCounted<PrefetchProxyPrefetchMetricsCollector>(
             page_->navigation_start_,
-            web_contents()->GetMainFrame()->GetPageUkmSourceId());
+            web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId());
   }
 
   // Add new prefetches, and update the type for any existing prefetches.
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor_unittest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor_unittest.cc
index 90f3e72..070525c 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor_unittest.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor_unittest.cc
@@ -118,7 +118,7 @@
 TEST_F(PrefetchProxyURLLoaderInterceptorTest, DISABLE_ASAN(WantIntercept)) {
   std::unique_ptr<TestPrefetchProxyURLLoaderInterceptor> interceptor =
       std::make_unique<TestPrefetchProxyURLLoaderInterceptor>(
-          web_contents()->GetMainFrame()->GetFrameTreeNodeId());
+          web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId());
 
   const GURL kTestUrl("https://test.com/path");
   interceptor->SetHasPrefetchedResponse(kTestUrl, true);
@@ -143,7 +143,7 @@
        DISABLE_ASAN(DoNotWantIntercept)) {
   std::unique_ptr<TestPrefetchProxyURLLoaderInterceptor> interceptor =
       std::make_unique<TestPrefetchProxyURLLoaderInterceptor>(
-          web_contents()->GetMainFrame()->GetFrameTreeNodeId());
+          web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId());
 
   const GURL kTestUrl("https://test.com/path");
   interceptor->SetHasPrefetchedResponse(kTestUrl, false);
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
index 6d759ba9..d0b89aea 100644
--- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
+++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -2369,7 +2369,7 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), search_url));
 
-  content::RenderFrameHost* frame = GetWebContents()->GetMainFrame();
+  content::RenderFrameHost* frame = GetWebContents()->GetPrimaryMainFrame();
 
   // Check the request total time is non-negative.
   int value = -1;
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.cc
index cb2da7e4..6af0629 100644
--- a/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.cc
+++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.cc
@@ -41,7 +41,7 @@
   }
 
   // Only intercept main frame requests.
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   if (!main_frame || main_frame->GetFrameTreeNodeId() != frame_tree_node_id) {
     return nullptr;
   }
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index bef51f0e..f3259af 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -91,7 +91,7 @@
   content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                     prerender_url);
   ASSERT_TRUE(
-      content::ExecJs(GetActiveWebContents()->GetMainFrame(),
+      content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                       content::JsReplace("location = $1", prerender_url)));
   activation_manager.WaitForNavigationFinished();
   EXPECT_TRUE(activation_manager.was_activated());
@@ -167,9 +167,9 @@
   prerender_helper().AddPrerender(prerender_url);
 
   // Accessing related attributes should also be recorded.
-  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetMainFrame(),
+  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                               "const value = document.prerendering;"));
-  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetMainFrame(),
+  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                               "document.onprerenderingchange = e => {};"));
 
   // Make sure the counts are stored by navigating away.
diff --git a/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc b/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc
index 3024d57..c1aa04a 100644
--- a/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc
+++ b/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc
@@ -703,7 +703,7 @@
   EXPECT_TRUE(IsPrerenderingNavigation());
 
   // Wait until the history is updated.
-  ASSERT_EQ(true, content::EvalJs(GetActiveWebContents()->GetMainFrame(),
+  ASSERT_EQ(true, content::EvalJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                                   "historyUpdated;"));
 
   EXPECT_EQ(1, prerender_helper().GetRequestCount(expected_prerender_url));
@@ -764,7 +764,7 @@
   EXPECT_TRUE(IsPrerenderingNavigation());
 
   // Wait until the history is updated.
-  EXPECT_EQ(true, content::EvalJs(GetActiveWebContents()->GetMainFrame(),
+  EXPECT_EQ(true, content::EvalJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                                   "historyUpdated;"));
 
   // The displayed url shouldn't contain the parameter of pf=cs.
@@ -819,7 +819,7 @@
   EXPECT_TRUE(IsPrerenderingNavigation());
 
   // Wait until the history is updated.
-  EXPECT_EQ(true, content::EvalJs(GetActiveWebContents()->GetMainFrame(),
+  EXPECT_EQ(true, content::EvalJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                                   "historyUpdated;"));
 
   // The displayed url shouldn't contain the parameter of pf=cs.
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index 69579f4..f69df74 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -1030,7 +1030,7 @@
   }
 
   content::RenderFrameHost* current_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   void ExpectBlocklistedFeature(
@@ -1306,7 +1306,8 @@
   TestPrintViewManager* print_view_manager =
       TestPrintViewManager::CreateForWebContents(web_contents);
 
-  content::ExecuteScriptAsync(web_contents->GetMainFrame(), "window.print();");
+  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
+                              "window.print();");
   print_view_manager->WaitUntilPreviewIsShownOrCancelled();
 
   // The non-printed document should have loaded the image, which will have
@@ -1345,7 +1346,7 @@
 
   content::WebContents* original_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = original_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = original_contents->GetPrimaryMainFrame();
   CreateTestPrintRenderFrame(rfh, original_contents);
   GetPrintRenderFrame(rfh)->PrintFrameContent(GetDefaultPrintFrameParams(),
                                               base::DoNothing());
@@ -1393,7 +1394,8 @@
   // Create composite client so subframe print message can be forwarded.
   PrintCompositeClient::CreateForWebContents(original_contents);
 
-  content::RenderFrameHost* main_frame = original_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      original_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = content::ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(child_frame);
   ASSERT_NE(child_frame, main_frame);
@@ -1439,7 +1441,8 @@
   // Create composite client so subframe print message can be forwarded.
   PrintCompositeClient::CreateForWebContents(original_contents);
 
-  content::RenderFrameHost* main_frame = original_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      original_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = content::ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(child_frame);
   ASSERT_NE(child_frame, main_frame);
@@ -1486,7 +1489,8 @@
 
   content::WebContents* original_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = original_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      original_contents->GetPrimaryMainFrame();
   ASSERT_TRUE(main_frame);
   content::RenderFrameHost* test_frame = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(test_frame);
@@ -1619,7 +1623,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(NavigateIframeToURL(original_contents, "iframe", isolated_url));
 
-  auto* main_frame = original_contents->GetMainFrame();
+  auto* main_frame = original_contents->GetPrimaryMainFrame();
   auto* subframe = ChildFrameAt(main_frame, 0);
   ASSERT_NE(main_frame->GetProcess(), subframe->GetProcess());
 
@@ -1737,7 +1741,8 @@
 
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
-  content::ExecuteScriptAsync(web_contents->GetMainFrame(), "window.print();");
+  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
+                              "window.print();");
   print_view_manager->WaitUntilPreviewIsShownOrCancelled();
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kAllowed);
@@ -1763,7 +1768,8 @@
 
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
-  content::ExecuteScriptAsync(web_contents->GetMainFrame(), "window.print();");
+  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
+                              "window.print();");
   print_view_manager->WaitUntilPreviewIsShownOrCancelled();
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
@@ -1787,7 +1793,8 @@
 
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
-  content::ExecuteScriptAsync(web_contents->GetMainFrame(), "window.print();");
+  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
+                              "window.print();");
   print_view_manager->WaitUntilPreviewIsShownOrCancelled();
   ASSERT_EQ(print_view_manager->GetPrintAllowance(),
             TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
@@ -1974,7 +1981,8 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   PrintPreviewObserver print_preview_observer(/*wait_for_loaded=*/false);
-  content::ExecuteScriptAsync(web_contents->GetMainFrame(), "window.print();");
+  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
+                              "window.print();");
   print_preview_observer.WaitUntilPreviewIsReady();
 }
 
@@ -1983,7 +1991,8 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   SetPrintingEnabledInterceptor main_frame_interceptor;
-  main_frame_interceptor.OverrideBinderForTesting(web_contents->GetMainFrame());
+  main_frame_interceptor.OverrideBinderForTesting(
+      web_contents->GetPrimaryMainFrame());
 
   // Clear `print_render_frames_` to use the overridden binder.
   auto* print_view_manager =
@@ -2096,7 +2105,7 @@
 IN_PROC_BROWSER_TEST_F(PrintPrerenderBrowserTest,
                        SetPrintingEnabledShouldNotBeCalledInPrerendering) {
   SetPrintingEnabledInterceptor interceptor;
-  interceptor.OverrideBinderForTesting(web_contents()->GetMainFrame());
+  interceptor.OverrideBinderForTesting(web_contents()->GetPrimaryMainFrame());
 
   // Clear `print_render_frames_` to use the overridden binder.
   auto* print_view_manager =
@@ -2209,8 +2218,8 @@
     GURL fenced_frame_url = https_server_.GetURL("/fenced_frames/title1.html");
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    content::RenderFrameHost* fenced_frame_host =
-        CreateFencedFrame(web_contents->GetMainFrame(), fenced_frame_url);
+    content::RenderFrameHost* fenced_frame_host = CreateFencedFrame(
+        web_contents->GetPrimaryMainFrame(), fenced_frame_url);
     ASSERT_TRUE(fenced_frame_host);
     content::WebContentsConsoleObserver console_observer(web_contents);
     EXPECT_EQ(0u, console_observer.messages().size());
@@ -2263,7 +2272,7 @@
     return;
 
   SetPrintingEnabledInterceptor interceptor;
-  interceptor.OverrideBinderForTesting(web_contents()->GetMainFrame());
+  interceptor.OverrideBinderForTesting(web_contents()->GetPrimaryMainFrame());
 
   // Clear `print_render_frames_` to use the overridden binder.
   auto* print_view_manager =
@@ -2285,7 +2294,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper()->CreateFencedFrame(
-          web_contents()->GetMainFrame(), kFencedFrameUrl);
+          web_contents()->GetPrimaryMainFrame(), kFencedFrameUrl);
   ASSERT_TRUE(fenced_frame_host);
 
   // The fenced frame should not call SetPrintingEnabled().
@@ -3553,7 +3562,7 @@
     auto* print_view_manager =
         TestPrintViewManagerForContentAnalysis::CreateForWebContents(
             web_contents);
-    content::ExecuteScriptAsync(web_contents->GetMainFrame(), script);
+    content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(), script);
 
     print_view_manager->WaitOnScanning();
     ASSERT_EQ(print_view_manager->scripted_print_called(),
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 44cc090..01df55a 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -294,7 +294,8 @@
 void PrintPreviewDialogController::RenderProcessGone(
     content::WebContents* web_contents,
     base::TerminationStatus status) {
-  content::RenderProcessHost* rph = web_contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* rph =
+      web_contents->GetPrimaryMainFrame()->GetProcess();
 
   // Store contents in a vector and deal with them after iterating through
   // `preview_dialog_map_` because RemoveFoo() can change `preview_dialog_map_`.
@@ -303,9 +304,9 @@
   for (auto& it : preview_dialog_map_) {
     WebContents* preview_dialog = it.first;
     WebContents* initiator = it.second;
-    if (preview_dialog->GetMainFrame()->GetProcess() == rph)
+    if (preview_dialog->GetPrimaryMainFrame()->GetProcess() == rph)
       closed_preview_dialogs.push_back(preview_dialog);
-    else if (initiator && initiator->GetMainFrame()->GetProcess() == rph)
+    else if (initiator && initiator->GetPrimaryMainFrame()->GetProcess() == rph)
       closed_initiators.push_back(initiator);
   }
 
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index aaf422d..dfd2b61 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -240,7 +240,7 @@
   // Make sure it is actually disabled for webpages.
   ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
   EXPECT_FALSE(filter->IsPluginAvailable(
-      initiator()->GetMainFrame()->GetProcess()->GetID(),
+      initiator()->GetPrimaryMainFrame()->GetProcess()->GetID(),
       pdf_external_plugin_info));
 
   PrintPreview();
@@ -262,7 +262,7 @@
     run_loop.Run();
 
     frame_count = 0;
-    preview_dialog->GetMainFrame()->ForEachRenderFrameHost(
+    preview_dialog->GetPrimaryMainFrame()->ForEachRenderFrameHost(
         base::BindLambdaForTesting(
             [&frame_count](content::RenderFrameHost* /*frame*/) {
               ++frame_count;
@@ -271,7 +271,7 @@
   ASSERT_EQ(kExpectedFrameCount, frame_count);
 
   // Make sure all the frames in the dialog has access to the PDF plugin.
-  preview_dialog->GetMainFrame()->ForEachRenderFrameHost(
+  preview_dialog->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating(&CheckPdfPluginForRenderFrame));
 
   PrintPreviewDone();
diff --git a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
index c264aab..62b757af 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
@@ -72,7 +72,7 @@
 
   // Get the preview dialog for initiator.
   PrintViewManager::FromWebContents(initiator)->PrintPreviewNow(
-      initiator->GetMainFrame(), false);
+      initiator->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog =
       dialog_controller->GetOrCreatePreviewDialog(initiator);
 
@@ -126,7 +126,7 @@
 
   // Create preview dialog for `web_contents_1`
   PrintViewManager::FromWebContents(web_contents_1)
-      ->PrintPreviewNow(web_contents_1->GetMainFrame(), false);
+      ->PrintPreviewNow(web_contents_1->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog_1 =
       dialog_controller->GetOrCreatePreviewDialog(web_contents_1);
 
@@ -135,7 +135,7 @@
 
   // Create preview dialog for `web_contents_2`
   PrintViewManager::FromWebContents(web_contents_2)
-      ->PrintPreviewNow(web_contents_2->GetMainFrame(), false);
+      ->PrintPreviewNow(web_contents_2->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog_2 =
       dialog_controller->GetOrCreatePreviewDialog(web_contents_2);
 
@@ -184,7 +184,7 @@
 
   // Get the preview dialog for the initiator.
   PrintViewManager::FromWebContents(initiator)->PrintPreviewNow(
-      initiator->GetMainFrame(), false);
+      initiator->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog =
       dialog_controller->GetOrCreatePreviewDialog(initiator);
 
@@ -238,7 +238,7 @@
   WebContents* tiger_preview_dialog =
       dialog_controller->GetOrCreatePreviewDialog(web_contents);
   PrintViewManager* manager = PrintViewManager::FromWebContents(web_contents);
-  manager->PrintPreviewNow(web_contents->GetMainFrame(), false);
+  manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false);
 
   // New print preview dialog is a constrained window, so the number of tabs is
   // still 1.
@@ -255,7 +255,8 @@
 
   // Print preview now should return true as the navigation should have closed
   // `tiger_preview_dialog` and the previous dialog should have closed.
-  EXPECT_TRUE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_TRUE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
   WebContents* tiger_barb_preview_dialog =
       dialog_controller->GetOrCreatePreviewDialog(web_contents);
   ASSERT_TRUE(tiger_barb_preview_dialog);
@@ -269,12 +270,14 @@
       tiger_barb_preview_dialog);
 
   // Now this returns false as `tiger_barb_preview_dialog` is open.
-  EXPECT_FALSE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_FALSE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
 
   // Navigate with back button or ALT+LEFT ARROW to a similar page.
   content::NavigationSimulator::GoBack(web_contents);
   EXPECT_EQ(tiger, web_contents->GetLastCommittedURL());
-  EXPECT_TRUE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_TRUE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
 
   // Get new dialog
   WebContents* tiger_preview_dialog_2 =
@@ -306,7 +309,8 @@
   // preview now should return false, dialog is still alive, and the dialog
   // returned by GetOrCreatePreviewDialog should be the same as the earlier
   // dialog.
-  EXPECT_FALSE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_FALSE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
   EXPECT_FALSE(tiger_2_destroyed.IsDestroyed());
   WebContents* tiger_preview_dialog_2b =
       dialog_controller->GetOrCreatePreviewDialog(web_contents);
@@ -317,7 +321,8 @@
   // Navigate with back button or ALT+LEFT ARROW to a similar page.
   content::NavigationSimulator::GoBack(web_contents);
   EXPECT_EQ(tiger, web_contents->GetLastCommittedURL());
-  EXPECT_TRUE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_TRUE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
 
   // Get new dialog
   WebContents* tiger_preview_dialog_3 =
@@ -347,7 +352,8 @@
   // preview now should return false, dialog is still alive, and the dialog
   // returned by GetOrCreatePreviewDialog should be the same as the earlier
   // dialog.
-  EXPECT_FALSE(manager->PrintPreviewNow(web_contents->GetMainFrame(), false));
+  EXPECT_FALSE(
+      manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(), false));
   EXPECT_FALSE(tiger_3_destroyed.IsDestroyed());
   WebContents* tiger_preview_dialog_3b =
       dialog_controller->GetOrCreatePreviewDialog(web_contents);
@@ -378,7 +384,7 @@
 
   // Create preview dialog for `web_contents_1`. Should not create a new tab.
   PrintViewManager::FromWebContents(web_contents_1)
-      ->PrintPreviewNow(web_contents_1->GetMainFrame(), false);
+      ->PrintPreviewNow(web_contents_1->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog_1 =
       dialog_controller->GetOrCreatePreviewDialog(web_contents_1);
   EXPECT_NE(web_contents_1, preview_dialog_1);
@@ -392,7 +398,7 @@
 
   // Create preview dialog for `web_contents_2`
   PrintViewManager::FromWebContents(web_contents_2)
-      ->PrintPreviewNow(web_contents_2->GetMainFrame(), false);
+      ->PrintPreviewNow(web_contents_2->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog_2 =
       dialog_controller->GetOrCreatePreviewDialog(web_contents_2);
   EXPECT_NE(web_contents_2, preview_dialog_2);
@@ -411,7 +417,7 @@
   // preview controller should exit cleanly and not crash.
   content::MockRenderProcessHost* rph =
       static_cast<content::MockRenderProcessHost*>(
-          web_contents_2->GetMainFrame()->GetProcess());
+          web_contents_2->GetPrimaryMainFrame()->GetProcess());
   rph->SimulateCrash();
 }
 
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 88a2f2b..3704cc6 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -524,9 +524,10 @@
 void PrintViewManagerBase::UpdatePrintingEnabled() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   // The Unretained() is safe because ForEachRenderFrameHost() is synchronous.
-  web_contents()->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      &PrintViewManagerBase::SendPrintingEnabled, base::Unretained(this),
-      printing_enabled_.GetValue()));
+  web_contents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(&PrintViewManagerBase::SendPrintingEnabled,
+                          base::Unretained(this),
+                          printing_enabled_.GetValue()));
 }
 
 void PrintViewManagerBase::NavigationStopped() {
@@ -870,7 +871,8 @@
   }
 
   // We can't print if there is no renderer.
-  if (!web_contents() || !web_contents()->GetMainFrame()->IsRenderFrameLive()) {
+  if (!web_contents() ||
+      !web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
     return false;
   }
 
@@ -917,7 +919,7 @@
     return false;
 
   // We can't print if there is no renderer.
-  if (!web_contents()->GetMainFrame()->IsRenderFrameLive()) {
+  if (!web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
     return false;
   }
 
diff --git a/chrome/browser/printing/print_view_manager_common.cc b/chrome/browser/printing/print_view_manager_common.cc
index 376dcc8..3ab701a 100644
--- a/chrome/browser/printing/print_view_manager_common.cc
+++ b/chrome/browser/printing/print_view_manager_common.cc
@@ -50,7 +50,7 @@
 #if BUILDFLAG(ENABLE_PDF)
   // Pick the plugin frame if `contents` is a PDF viewer guest.
   content::RenderFrameHost* pdf_rfh =
-      pdf_frame_util::FindPdfChildFrame(contents->GetMainFrame());
+      pdf_frame_util::FindPdfChildFrame(contents->GetPrimaryMainFrame());
   if (pdf_rfh)
     return pdf_rfh;
 #endif
@@ -117,7 +117,7 @@
   auto* focused_frame = contents->GetFocusedFrame();
   return (focused_frame && focused_frame->HasSelection())
              ? focused_frame
-             : contents->GetMainFrame();
+             : contents->GetPrimaryMainFrame();
 }
 
 content::WebContents* GetWebContentsToUse(content::WebContents* contents) {
diff --git a/chrome/browser/printing/print_view_manager_unittest.cc b/chrome/browser/printing/print_view_manager_unittest.cc
index 0ef75bd..0d01763 100644
--- a/chrome/browser/printing/print_view_manager_unittest.cc
+++ b/chrome/browser/printing/print_view_manager_unittest.cc
@@ -282,7 +282,7 @@
   ASSERT_TRUE(web_contents);
 
   content::RenderFrameHost* sub_frame =
-      content::RenderFrameHostTester::For(web_contents->GetMainFrame())
+      content::RenderFrameHostTester::For(web_contents->GetPrimaryMainFrame())
           ->AppendChild("child");
 
   PrintViewManager* print_view_manager =
@@ -320,7 +320,8 @@
       std::make_unique<TestPrintViewManager>(web_contents);
   PrintViewManager::SetReceiverImplForTesting(print_view_manager.get());
 
-  print_view_manager->PrintPreviewNow(web_contents->GetMainFrame(), false);
+  print_view_manager->PrintPreviewNow(web_contents->GetPrimaryMainFrame(),
+                                      false);
 
   base::Value::Dict print_ticket = GetPrintTicket(mojom::PrinterType::kLocal);
   const char kTestData[] = "abc";
@@ -330,7 +331,7 @@
       base::BindOnce(&TestPrintViewManager::FakePrintCallback,
                      base::Unretained(print_view_manager.get()));
   print_view_manager->PrintForPrintPreview(std::move(print_ticket), print_data,
-                                           web_contents->GetMainFrame(),
+                                           web_contents->GetPrimaryMainFrame(),
                                            std::move(callback));
   print_view_manager->WaitForCallback();
 
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index ad78fb5..d9fa622 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -264,8 +264,8 @@
                  content::WebContents* web_contents) {
     if (!web_contents)
       web_contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
-    return content::ExecuteScriptAndExtractString(web_contents->GetMainFrame(),
-                                                  script, result);
+    return content::ExecuteScriptAndExtractString(
+        web_contents->GetPrimaryMainFrame(), script, result);
   }
 
   gcm::GCMAppHandler* GetAppHandler() {
@@ -2017,7 +2017,8 @@
 
   auto* web_contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
   LOG(ERROR) << web_contents->GetLastCommittedURL();
-  auto* subframe = content::ChildFrameAt(web_contents->GetMainFrame(), 0u);
+  auto* subframe =
+      content::ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0u);
   ASSERT_TRUE(subframe);
 
   // A cross-origin subframe that had not been granted the NOTIFICATIONS
@@ -2843,7 +2844,7 @@
   console_observer.SetPattern(kIncognitoWarningPattern);
 
   // Filter out the main frame host of the currently active page.
-  content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame();
   console_observer.SetFilter(base::BindLambdaForTesting(
       [&](const content::WebContentsConsoleObserver::Message& message) {
         return message.source_frame == rfh;
@@ -2877,7 +2878,7 @@
   // prerender page activation.
   std::string script_result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
-      web_contents()->GetMainFrame(), "registerServiceWorker()",
+      web_contents()->GetPrimaryMainFrame(), "registerServiceWorker()",
       &script_result));
   ASSERT_EQ("ok - service worker registered", script_result);
 
diff --git a/chrome/browser/push_messaging/push_messaging_notification_manager.cc b/chrome/browser/push_messaging/push_messaging_notification_manager.cc
index 5b403b2..9e089d2 100644
--- a/chrome/browser/push_messaging/push_messaging_notification_manager.cc
+++ b/chrome/browser/push_messaging/push_messaging_notification_manager.cc
@@ -212,7 +212,7 @@
     Profile* profile,
     WebContents* active_web_contents,
     const GURL& origin) {
-  if (!active_web_contents || !active_web_contents->GetMainFrame())
+  if (!active_web_contents || !active_web_contents->GetPrimaryMainFrame())
     return false;
 
   // Don't leak information from other profiles.
@@ -220,7 +220,7 @@
     return false;
 
   // Ignore minimized windows.
-  switch (active_web_contents->GetMainFrame()->GetVisibilityState()) {
+  switch (active_web_contents->GetPrimaryMainFrame()->GetVisibilityState()) {
     case content::PageVisibilityState::kHidden:
     case content::PageVisibilityState::kHiddenButPainting:
       return false;
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc
index 5975212..3986160 100644
--- a/chrome/browser/referrer_policy_browsertest.cc
+++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -258,11 +258,15 @@
       mouse_event.button = button;
       mouse_event.SetPositionInWidget(15, 15);
       mouse_event.click_count = 1;
-      tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-          mouse_event);
+      tab->GetPrimaryMainFrame()
+          ->GetRenderViewHost()
+          ->GetWidget()
+          ->ForwardMouseEvent(mouse_event);
       mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-      tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-          mouse_event);
+      tab->GetPrimaryMainFrame()
+          ->GetRenderViewHost()
+          ->GetWidget()
+          ->ForwardMouseEvent(mouse_event);
     }
 
     if (disposition == WindowOpenDisposition::CURRENT_TAB) {
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
index a67a63e..3c9d31b8 100644
--- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
+++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
@@ -212,7 +212,7 @@
 
 void LinkToTextMenuObserver::RequestLinkGeneration() {
   content::RenderFrameHost* main_frame =
-      proxy_->GetWebContents()->GetMainFrame();
+      proxy_->GetWebContents()->GetPrimaryMainFrame();
   if (!main_frame)
     return;
 
@@ -292,7 +292,7 @@
 
 void LinkToTextMenuObserver::ReshareLink() {
   // Get the list of RenderFrameHosts from the current page.
-  proxy_->GetWebContents()->GetMainFrame()->ForEachRenderFrameHost(
+  proxy_->GetWebContents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating(
           [](std::vector<content::GlobalRenderFrameHostId>*
                  render_frame_host_ids,
@@ -362,7 +362,7 @@
 
 void LinkToTextMenuObserver::RemoveHighlights() {
   // Remove highlights from all frames in the primary page.
-  proxy_->GetWebContents()->GetMainFrame()->ForEachRenderFrameHost(
+  proxy_->GetWebContents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating(RemoveHighlightsInFrame));
 
   execute_command_pending_ = false;
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
index dd5bd4f..f943bca 100644
--- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
+++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
@@ -93,7 +93,7 @@
 
     auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
     menu()->set_web_contents(web_contents);
-    content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_TRUE(ExecuteScript(main_frame, "window.focus();"));
   }
   void TearDownOnMainThread() override {
@@ -122,7 +122,7 @@
 
   content::RenderFrameHost* getRenderFrameHost() {
     auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   }
 
  private:
@@ -233,7 +233,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame_a = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame_a = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame_b = ChildFrameAt(main_frame_a, 0);
   EXPECT_TRUE(ExecuteScript(child_frame_b, "window.focus();"));
   EXPECT_EQ(child_frame_b, web_contents->GetFocusedFrame());
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc
index 12432a56..0041524 100644
--- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc
@@ -48,7 +48,7 @@
   void ShowMenu(const content::ContextMenuParams& params) {
     auto* web_contents = chrome_test_utils::GetActiveWebContents(this);
     menu()->set_web_contents(web_contents);
-    content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_TRUE(ExecuteScript(main_frame, "window.focus();"));
 
     observer_->OnContextMenuShown(params, gfx::Rect());
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 9d871de..0467763 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -850,7 +850,7 @@
   if (web_view_guest) {
     key = MenuItem::ExtensionKey(extension->id(),
                                  web_view_guest->owner_web_contents()
-                                     ->GetMainFrame()
+                                     ->GetPrimaryMainFrame()
                                      ->GetProcess()
                                      ->GetID(),
                                  web_view_guest->view_instance_id());
@@ -1157,7 +1157,7 @@
        lens::features::GetEnableUKMLoggingForImageSearch())) {
     // Enum id should correspond to the RenderViewContextMenuItem enum.
     ukm::SourceId source_id =
-        source_web_contents_->GetMainFrame()->GetPageUkmSourceId();
+        source_web_contents_->GetPrimaryMainFrame()->GetPageUkmSourceId();
     ukm::builders::RenderViewContextMenu_Used(source_id)
         .SetSelectedMenuItem(enum_id)
         .Record(ukm::UkmRecorder::Get());
@@ -2661,7 +2661,7 @@
       break;
 
     case IDC_VIEW_SOURCE:
-      embedder_web_contents_->GetMainFrame()->ViewSource();
+      embedder_web_contents_->GetPrimaryMainFrame()->ViewSource();
       break;
 
     case IDC_CONTENT_CONTEXT_INSPECTELEMENT:
@@ -3631,11 +3631,11 @@
   // main frame when Pepper-free PDF viewer is enabled. To trigger any plugin
   // action, we need to detect this child frame and trigger the actions from
   // there.
-  plugin_rfh =
-      pdf_frame_util::FindPdfChildFrame(source_web_contents_->GetMainFrame());
+  plugin_rfh = pdf_frame_util::FindPdfChildFrame(
+      source_web_contents_->GetPrimaryMainFrame());
 #endif
   if (!plugin_rfh)
-    plugin_rfh = source_web_contents_->GetMainFrame();
+    plugin_rfh = source_web_contents_->GetPrimaryMainFrame();
 
   // TODO(crbug.com/776807): See if this needs to be done for OOPIFs as well.
   // Calculate the local location in view coordinates inside the plugin before
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index 841583a..442fad5 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -192,7 +192,7 @@
     params.writing_direction_right_to_left = 0;
 #endif
     auto menu = std::make_unique<TestRenderViewContextMenu>(
-        *web_contents->GetMainFrame(), params);
+        *web_contents->GetPrimaryMainFrame(), params);
     menu->Init();
     return menu;
   }
@@ -229,7 +229,7 @@
     params.writing_direction_right_to_left = 0;
 #endif
     auto menu = std::make_unique<TestRenderViewContextMenu>(
-        *web_contents->GetMainFrame(), params);
+        *web_contents->GetPrimaryMainFrame(), params);
     menu->Init();
     return menu;
   }
@@ -288,7 +288,7 @@
     browser()
         ->tab_strip_model()
         ->GetActiveWebContents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->GetRemoteAssociatedInterfaces()
         ->GetInterface(&chrome_render_frame);
 
@@ -389,9 +389,9 @@
 
     // Get the PDF extension main frame. The context menu will be created inside
     // this frame.
-    extension_frame_ = guest_contents->GetMainFrame();
+    extension_frame_ = guest_contents->GetPrimaryMainFrame();
     EXPECT_TRUE(extension_frame_);
-    EXPECT_NE(extension_frame_, web_contents->GetMainFrame());
+    EXPECT_NE(extension_frame_, web_contents->GetPrimaryMainFrame());
 
     content::ContextMenuParams params;
     params.page_url = page_url;
@@ -432,7 +432,7 @@
     guest->WaitForGuestAttached();
     ASSERT_NE(web_contents, guest_contents);
     // Get the pdf plugin's main frame.
-    content::RenderFrameHost* frame = guest_contents->GetMainFrame();
+    content::RenderFrameHost* frame = guest_contents->GetPrimaryMainFrame();
     ASSERT_TRUE(frame);
 
     content::ContextMenuParams params;
@@ -738,9 +738,11 @@
   content::ContextMenuParams params;
   params.media_type = blink::mojom::ContextMenuDataMediaType::kCanvas;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   ASSERT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
@@ -752,9 +754,11 @@
   content::ContextMenuParams params;
   params.is_editable = true;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_EQ(ui::IsEmojiPanelSupported(),
@@ -766,9 +770,11 @@
   content::ContextMenuParams params;
   params.is_editable = false;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   // Emoji context menu item should never be present on a non-editable field.
@@ -783,7 +789,8 @@
   std::unique_ptr<content::WebContents> detached_web_contents =
       content::WebContents::Create(
           content::WebContents::CreateParams(browser()->profile()));
-  TestRenderViewContextMenu menu(*detached_web_contents->GetMainFrame(), {});
+  TestRenderViewContextMenu menu(*detached_web_contents->GetPrimaryMainFrame(),
+                                 {});
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_EMOJI, 0);
 }
@@ -794,7 +801,8 @@
   std::unique_ptr<content::WebContents> detached_web_contents =
       content::WebContents::Create(
           content::WebContents::CreateParams(browser()->profile()));
-  TestRenderViewContextMenu menu(*detached_web_contents->GetMainFrame(), {});
+  TestRenderViewContextMenu menu(*detached_web_contents->GetPrimaryMainFrame(),
+                                 {});
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_EMOJI, 0);
 }
@@ -810,9 +818,11 @@
   content::ContextMenuParams params;
   params.is_editable = true;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   // If there's no callback, the emoji context menu should not be present.
@@ -874,11 +884,15 @@
   gfx::Rect offset = tab->GetContainerBounds();
   mouse_event.SetPositionInScreen(15 + offset.x(), 15 + offset.y());
   mouse_event.click_count = 1;
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   // The menu_observer will select "Open in new tab", wait for the new tab to
   // be added.
@@ -905,9 +919,11 @@
   context_menu_params.page_url = page;
 
   // Select "Open Link in New Tab" and wait for the new tab to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -934,9 +950,11 @@
   context_menu_params.page_url = page;
 
   // Select "Open Link in New Tab" and wait for the new tab to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -968,9 +986,11 @@
   context_menu_params.link_url = echoheader;
 
   // Select "Open Link in New Tab" and wait for the new tab to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -1017,9 +1037,11 @@
   context_menu_params.link_url = echoheader;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -1068,7 +1090,7 @@
   content::ContextMenuParams params;
   params.page_url = GURL("https://www.example.com/");
   params.link_url = start_url;
-  TestRenderViewContextMenu menu(*initial_tab->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*initial_tab->GetPrimaryMainFrame(), params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP,
                       0 /* event_flags */);
@@ -1105,11 +1127,15 @@
   mouse_event.SetPositionInWidget(15, 15);
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   // Wait for context menu to be visible.
   menu_observer.WaitForMenuOpenAndClose();
@@ -1137,11 +1163,15 @@
   mouse_event.SetPositionInWidget(2, 2);  // This is over the main frame.
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   // Wait for context menu to be visible.
   menu_observer.WaitForMenuOpenAndClose();
@@ -1194,11 +1224,15 @@
       blink::WebInputEvent::GetStaticTimeStampForTests());
   mouse_event.button = blink::WebMouseEvent::Button::kRight;
   mouse_event.SetPositionInWidget(25, 25);  // This is over the subframe.
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   // Wait for context menu to be visible.
   menu_observer.WaitForMenuOpenAndClose();
@@ -1329,11 +1363,15 @@
   mouse_event.SetPositionInWidget(15, 15);
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
   mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-  tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  tab->GetPrimaryMainFrame()
+      ->GetRenderViewHost()
+      ->GetWidget()
+      ->ForwardMouseEvent(mouse_event);
 
   // Wait for context menu to be visible.
   menu_observer.WaitForMenuOpenAndClose();
@@ -1541,9 +1579,11 @@
   context_menu_params.link_url = echoheader;
   context_menu_params.src_url = echoheader;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
 
   // Verify that the Open in Profile option is shown.
@@ -1593,7 +1633,10 @@
       delete;
 
   content::RenderFrameHost* primary_main_frame_host() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
   content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
@@ -2057,7 +2100,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->GetRemoteAssociatedInterfaces()
       ->GetInterface(&chrome_render_frame);
 
@@ -2301,9 +2344,11 @@
   params.media_type = blink::mojom::ContextMenuDataMediaType::kVideo;
   params.media_flags |= blink::ContextMenuData::kMediaCanPictureInPicture;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_PICTUREINPICTURE));
@@ -2317,9 +2362,11 @@
   params.media_flags |= blink::ContextMenuData::kMediaCanPictureInPicture;
   params.media_flags |= blink::ContextMenuData::kMediaPictureInPicture;
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_PICTUREINPICTURE));
@@ -2485,9 +2532,11 @@
   content::ContextMenuParams params;
   params.is_editable = true;
   std::unique_ptr<TestRenderViewContextMenu> menu3 =
-      std::make_unique<TestRenderViewContextMenu>(
-          *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          params);
+      std::make_unique<TestRenderViewContextMenu>(*browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                  params);
   menu3->Init();
   ASSERT_TRUE(menu3->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_IN_READ_ANYTHING));
 }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_interactive_uitest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_interactive_uitest.cc
index ab1810d..42cb7717 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_interactive_uitest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_interactive_uitest.cc
@@ -48,7 +48,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* subframe = content::ChildFrameAt(main_frame, 0);
   ASSERT_NE(main_frame->GetLastCommittedOrigin(),
             subframe->GetLastCommittedOrigin());
@@ -101,7 +101,7 @@
   // SiteInstance.
   EXPECT_TRUE(WaitForLoadStop(new_web_contents));
   EXPECT_EQ(link_url, new_web_contents->GetLastCommittedURL());
-  EXPECT_EQ(new_web_contents->GetMainFrame()->GetSiteInstance(),
+  EXPECT_EQ(new_web_contents->GetPrimaryMainFrame()->GetSiteInstance(),
             subframe->GetSiteInstance());
 }
 #endif  // !BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.cc
index b7c52a64..19f2009 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.cc
@@ -34,7 +34,7 @@
   params.link_url = link_url;
   params.frame_url = frame_url;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
   return menu;
 }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
index a9cb88d..a817e20 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -118,7 +118,7 @@
   content::ContextMenuParams params = CreateParams(MenuItem::LINK);
   params.unfiltered_link_url = params.link_url;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents->GetMainFrame(), params);
+      *web_contents->GetPrimaryMainFrame(), params);
   menu->set_protocol_handler_registry(registry);
   menu->Init();
   return menu;
@@ -484,7 +484,7 @@
     params.unfiltered_link_url = params.link_url =
         GURL(chrome::kChromeUISettingsURL);
     auto menu = std::make_unique<TestRenderViewContextMenu>(
-        *web_contents()->GetMainFrame(), params);
+        *web_contents()->GetPrimaryMainFrame(), params);
     menu->set_protocol_handler_registry(registry_.get());
     menu->Init();
     return menu;
@@ -543,7 +543,7 @@
   content::ContextMenuParams params = CreateParams(MenuItem::SELECTION);
   params.page_url = GURL("http://www.foo.com/");
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->set_dlp_rules_manager(nullptr);
   menu->set_selection_navigation_url(GURL("http://www.bar.com/"));
 
@@ -599,7 +599,7 @@
   params.unfiltered_link_url = params.link_url;
   params.has_image_contents = false;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   AppendImageItems(menu.get());
 
   ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_LOAD_IMAGE));
@@ -612,7 +612,7 @@
   content::ContextMenuParams params = CreateParams(MenuItem::VIDEO);
   params.suggested_filename = kTestSuggestedFileName;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEAVAS, 0 /* event_flags */);
 
   // Video item should have suggested file name.
@@ -623,7 +623,7 @@
   params = CreateParams(MenuItem::AUDIO);
   params.suggested_filename = kTestSuggestedFileName;
   menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEAVAS, 0 /* event_flags */);
 
   // Audio item should have suggested file name.
@@ -637,7 +637,7 @@
 TEST_F(RenderViewContextMenuPrefsTest, OpenLinkNavigationParamsSet) {
   TestNavigationDelegate delegate;
   web_contents()->SetDelegate(&delegate);
-  content::RenderFrameHost& main_frame = *web_contents()->GetMainFrame();
+  content::RenderFrameHost& main_frame = *web_contents()->GetPrimaryMainFrame();
 
   content::ContextMenuParams params = CreateParams(MenuItem::LINK);
   params.unfiltered_link_url = params.link_url;
@@ -662,7 +662,7 @@
 TEST_F(RenderViewContextMenuPrefsTest, OpenLinkNavigationInitiatorSet) {
   TestNavigationDelegate delegate;
   web_contents()->SetDelegate(&delegate);
-  content::RenderFrameHost& main_frame = *web_contents()->GetMainFrame();
+  content::RenderFrameHost& main_frame = *web_contents()->GetPrimaryMainFrame();
 
   content::ContextMenuParams params = CreateParams(MenuItem::LINK);
   params.unfiltered_link_url = params.link_url;
@@ -689,7 +689,7 @@
   params.input_field_type =
       blink::mojom::ContextMenuDataInputFieldType::kPassword;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->Init();
 
   EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_SHOWALLSAVEDPASSWORDS));
@@ -712,7 +712,7 @@
   params.input_field_type =
       blink::mojom::ContextMenuDataInputFieldType::kPassword;
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *incognito_web_contents->GetMainFrame(), params);
+      *incognito_web_contents->GetPrimaryMainFrame(), params);
   menu->Init();
 
   EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_SHOWALLSAVEDPASSWORDS));
@@ -748,7 +748,7 @@
       CreateParams(MenuItem::SELECTION | MenuItem::EDITABLE);
   params.page_url = chrome::GetSettingsUrl(chrome::kPasswordManagerSubPage);
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->set_selection_navigation_url(GURL("https://www.foo.com/"));
   menu->Init();
 
@@ -762,7 +762,7 @@
       CreateParams(MenuItem::SELECTION | MenuItem::EDITABLE);
   params.page_url = chrome::GetSettingsUrl(chrome::kPasswordCheckSubPage);
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents()->GetMainFrame(), params);
+      *web_contents()->GetPrimaryMainFrame(), params);
   menu->set_selection_navigation_url(GURL("https://www.foo.com/"));
   menu->Init();
 
@@ -783,7 +783,8 @@
         web_contents()->GetLastCommittedURL(),
         TabWebFeedFollowState::kNotFollowed, std::string());
     content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-    TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+    TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                   params);
     menu.Init();
     EXPECT_TRUE(menu.IsItemPresent(IDC_FOLLOW));
     EXPECT_FALSE(menu.IsItemPresent(IDC_UNFOLLOW));
@@ -795,7 +796,8 @@
         web_contents()->GetLastCommittedURL(), TabWebFeedFollowState::kFollowed,
         std::string());
     content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-    TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+    TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                   params);
     menu.Init();
     EXPECT_FALSE(menu.IsItemPresent(IDC_FOLLOW));
     EXPECT_TRUE(menu.IsItemPresent(IDC_UNFOLLOW));
@@ -808,7 +810,8 @@
         web_contents()->GetLastCommittedURL(), TabWebFeedFollowState::kUnknown,
         std::string());
     content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-    TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+    TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                   params);
     menu.Init();
     EXPECT_FALSE(menu.IsItemPresent(IDC_FOLLOW));
     EXPECT_FALSE(menu.IsItemPresent(IDC_FOLLOW));
@@ -824,7 +827,8 @@
   SetUserSelectedDefaultSearchProvider("https://www.google.com",
                                        /*supports_image_search=*/true);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
@@ -841,7 +845,8 @@
   // Set enterprise policy to false.
   profile()->GetPrefs()->SetBoolean(prefs::kLensRegionSearchEnabled, false);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
@@ -856,7 +861,8 @@
                                        /*supports_image_search=*/true);
   content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
   params.has_image_contents = true;
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   AppendImageItems(&menu);
 
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
@@ -872,7 +878,8 @@
   SetUserSelectedDefaultSearchProvider("https://www.search.com",
                                        /*supports_image_search=*/true);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_WEB_REGION_SEARCH));
@@ -888,7 +895,8 @@
   SetUserSelectedDefaultSearchProvider("https://www.search.com",
                                        /*supports_image_search=*/false);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_WEB_REGION_SEARCH));
@@ -903,7 +911,8 @@
   SetUserSelectedDefaultSearchProvider("https://www.google.com",
                                        /*supports_image_search=*/true);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
@@ -918,7 +927,8 @@
                                        /*supports_image_search=*/true);
   content::ContextMenuParams params = CreateParams(MenuItem::PAGE);
   params.page_url = GURL(chrome::kChromeUISettingsURL);
-  TestRenderViewContextMenu menu(*web_contents()->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
   menu.Init();
 
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
index 71e2a8f..0cb6af3c 100644
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -176,7 +176,7 @@
 
     EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
     tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
-    rph1 = tab1->GetMainFrame()->GetProcess();
+    rph1 = tab1->GetPrimaryMainFrame()->GetProcess();
     EXPECT_EQ(omnibox, tab1->GetURL());
     EXPECT_EQ(host_count, RenderProcessHostCount());
 
@@ -191,7 +191,7 @@
     host_count++;
     EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
     tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
-    rph2 = tab1->GetMainFrame()->GetProcess();
+    rph2 = tab1->GetPrimaryMainFrame()->GetProcess();
     EXPECT_EQ(tab1->GetURL(), page1);
     EXPECT_EQ(host_count, RenderProcessHostCount());
     EXPECT_NE(rph1, rph2);
@@ -211,9 +211,9 @@
     EXPECT_EQ(tab2->GetURL(), page2);
     EXPECT_EQ(host_count, RenderProcessHostCount());
     if (content::AreAllSitesIsolatedForTesting())
-      EXPECT_NE(tab2->GetMainFrame()->GetProcess(), rph2);
+      EXPECT_NE(tab2->GetPrimaryMainFrame()->GetProcess(), rph2);
     else
-      EXPECT_EQ(tab2->GetMainFrame()->GetProcess(), rph2);
+      EXPECT_EQ(tab2->GetPrimaryMainFrame()->GetProcess(), rph2);
 
     // Create another WebUI tab.  Each WebUI tab should get a separate process
     // because of origin locking.
@@ -230,7 +230,7 @@
     tab2 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
     EXPECT_EQ(tab2->GetURL(), GURL(history));
     EXPECT_EQ(host_count, RenderProcessHostCount());
-    EXPECT_NE(tab2->GetMainFrame()->GetProcess(), rph1);
+    EXPECT_NE(tab2->GetPrimaryMainFrame()->GetProcess(), rph1);
 
     // Create an extension tab.  It should be in its own process.
     GURL extension_url("chrome-extension://" + extension->id());
@@ -242,7 +242,7 @@
     host_count++;
     EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
     tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
-    rph3 = tab1->GetMainFrame()->GetProcess();
+    rph3 = tab1->GetPrimaryMainFrame()->GetProcess();
     EXPECT_EQ(tab1->GetURL(), extension_url);
     EXPECT_EQ(host_count, RenderProcessHostCount());
     EXPECT_NE(rph1, rph3);
@@ -364,13 +364,13 @@
 
   void VerifyProcessIsBackgrounded(WebContents* web_contents) {
     constexpr bool kExpectedIsBackground = true;
-    VerifyProcessPriority(web_contents->GetMainFrame()->GetProcess(),
+    VerifyProcessPriority(web_contents->GetPrimaryMainFrame()->GetProcess(),
                           kExpectedIsBackground);
   }
 
   void VerifyProcessIsForegrounded(WebContents* web_contents) {
     constexpr bool kExpectedIsBackground = false;
-    VerifyProcessPriority(web_contents->GetMainFrame()->GetProcess(),
+    VerifyProcessPriority(web_contents->GetPrimaryMainFrame()->GetProcess(),
                           kExpectedIsBackground);
   }
 
@@ -437,8 +437,8 @@
   WebContents* tab2 = ShowSingletonTab(page2);
   {
     SCOPED_TRACE("TEST STEP: 2nd tab opened in foreground");
-    EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
-              tab2->GetMainFrame()->GetProcess());
+    EXPECT_NE(tab1->GetPrimaryMainFrame()->GetProcess(),
+              tab2->GetPrimaryMainFrame()->GetProcess());
     EXPECT_PROCESS_IS_BACKGROUNDED(tab1);
     EXPECT_PROCESS_IS_FOREGROUNDED(tab2);
   }
@@ -449,10 +449,10 @@
   WebContents* tab3 = OpenBackgroundTab(page3);
   {
     SCOPED_TRACE("TEST STEP: 3rd tab opened in background");
-    EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
-              tab3->GetMainFrame()->GetProcess());
-    EXPECT_NE(tab2->GetMainFrame()->GetProcess(),
-              tab3->GetMainFrame()->GetProcess());
+    EXPECT_NE(tab1->GetPrimaryMainFrame()->GetProcess(),
+              tab3->GetPrimaryMainFrame()->GetProcess());
+    EXPECT_NE(tab2->GetPrimaryMainFrame()->GetProcess(),
+              tab3->GetPrimaryMainFrame()->GetProcess());
     EXPECT_PROCESS_IS_BACKGROUNDED(tab1);
     EXPECT_PROCESS_IS_FOREGROUNDED(tab2);
     EXPECT_PROCESS_IS_BACKGROUNDED(tab3);
@@ -617,10 +617,10 @@
   nav_observer.Wait();
 
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_EQ(wc1->GetMainFrame()->GetLastCommittedURL(),
-            wc2->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(wc1->GetMainFrame()->GetProcess(),
-            wc2->GetMainFrame()->GetProcess());
+  EXPECT_EQ(wc1->GetPrimaryMainFrame()->GetLastCommittedURL(),
+            wc2->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(wc1->GetPrimaryMainFrame()->GetProcess(),
+            wc2->GetPrimaryMainFrame()->GetProcess());
 
   // Create an object that will close the window on a process crash.
   WindowDestroyer destroyer(wc1, browser()->tab_strip_model());
@@ -629,7 +629,7 @@
   // method to be called. Alternatively, RenderProcessHost::OnChannelError can
   // be called to directly force a call to ProcessDied.
   content::ScopedAllowRendererCrashes allow_renderer_crashes(wc1);
-  wc1->GetMainFrame()->GetProcess()->Shutdown(-1);
+  wc1->GetPrimaryMainFrame()->GetProcess()->Shutdown(-1);
 
   destroyer.Wait();
 }
@@ -679,13 +679,14 @@
 
     // Create a new tab for the no audio page and confirm that the process of
     // each tab is different and that both are valid.
-    audio_process_ = ProcessFromHandle(audio_tab_web_contents_->GetMainFrame()
-                                           ->GetProcess()
-                                           ->GetProcess()
-                                           .Handle());
+    audio_process_ =
+        ProcessFromHandle(audio_tab_web_contents_->GetPrimaryMainFrame()
+                              ->GetProcess()
+                              ->GetProcess()
+                              .Handle());
     WebContents* wc = ShowSingletonTab(no_audio_url_);
     no_audio_process_ = ProcessFromHandle(
-        wc->GetMainFrame()->GetProcess()->GetProcess().Handle());
+        wc->GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle());
     ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid());
     ASSERT_TRUE(no_audio_process_.IsValid());
     ASSERT_TRUE(audio_process_.IsValid());
diff --git a/chrome/browser/reputation/reputation_web_contents_observer.cc b/chrome/browser/reputation/reputation_web_contents_observer.cc
index 3fd3034..2eca5725 100644
--- a/chrome/browser/reputation/reputation_web_contents_observer.cc
+++ b/chrome/browser/reputation/reputation_web_contents_observer.cc
@@ -177,9 +177,10 @@
 
 void ReputationWebContentsObserver::OnVisibilityChanged(
     content::Visibility visibility) {
-  MaybeShowSafetyTip(web_contents()->GetMainFrame()->GetPageUkmSourceId(),
-                     /*called_from_visibility_check=*/true,
-                     /*record_ukm_if_tip_not_shown=*/false);
+  MaybeShowSafetyTip(
+      web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
+      /*called_from_visibility_check=*/true,
+      /*record_ukm_if_tip_not_shown=*/false);
 }
 
 security_state::SafetyTipInfo
@@ -220,7 +221,7 @@
     ukm::SourceId navigation_source_id,
     bool called_from_visibility_check,
     bool record_ukm_if_tip_not_shown) {
-  if (web_contents()->GetMainFrame()->GetVisibilityState() !=
+  if (web_contents()->GetPrimaryMainFrame()->GetVisibilityState() !=
       content::PageVisibilityState::kVisible) {
     MaybeCallReputationCheckCallback(false);
     return;
@@ -305,7 +306,7 @@
   // Log a console message if it's the first time we're going to open the Safety
   // Tip. (Otherwise, we'd print the message each time the tab became visible.)
   if (!called_from_visibility_check) {
-    web_contents()->GetMainFrame()->AddMessageToConsole(
+    web_contents()->GetPrimaryMainFrame()->AddMessageToConsole(
         blink::mojom::ConsoleMessageLevel::kWarning,
         base::StringPrintf(
             "Chrome has determined that %s could be fake or fraudulent.\n\n"
diff --git a/chrome/browser/resource_coordinator/session_restore_policy.cc b/chrome/browser/resource_coordinator/session_restore_policy.cc
index ddeb539..15ca094 100644
--- a/chrome/browser/resource_coordinator/session_restore_policy.cc
+++ b/chrome/browser/resource_coordinator/session_restore_policy.cc
@@ -209,7 +209,8 @@
       contents->GetBrowserContext()->GetPermissionController();
 
   if (permission_controller->GetPermissionStatusForCurrentDocument(
-          blink::PermissionType::NOTIFICATIONS, contents->GetMainFrame()) ==
+          blink::PermissionType::NOTIFICATIONS,
+          contents->GetPrimaryMainFrame()) ==
       blink::mojom::PermissionStatus::GRANTED) {
     used_in_bg = true;
   }
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher.cc b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
index 16defeb..10b81ae 100644
--- a/chrome/browser/resource_coordinator/tab_activity_watcher.cc
+++ b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
@@ -200,7 +200,7 @@
       : WebContentsObserver(web_contents),
         content::WebContentsUserData<WebContentsData>(*web_contents) {
     DCHECK(!web_contents->GetBrowserContext()->IsOffTheRecord());
-    web_contents->GetMainFrame()
+    web_contents->GetPrimaryMainFrame()
         ->GetRenderViewHost()
         ->GetWidget()
         ->AddInputEventObserver(this);
@@ -208,7 +208,7 @@
     creation_time_ = NowTicks();
 
     // A navigation may already have completed if this is a replacement tab.
-    ukm_source_id_ = web_contents->GetMainFrame()->GetPageUkmSourceId();
+    ukm_source_id_ = web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
     // When a tab is discarded, a new null_web_contents will be created (with
     // WasDiscarded set as true) applied as a replacement of the discarded tab.
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc b/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc
index 43ac0d7..1db94bb7 100644
--- a/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc
@@ -543,7 +543,7 @@
 
   // Fake some input events.
   content::RenderWidgetHost* widget_1 =
-      test_contents_1->GetMainFrame()->GetRenderViewHost()->GetWidget();
+      test_contents_1->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
   widget_1->ForwardMouseEvent(
       CreateMouseEvent(WebInputEvent::Type::kMouseDown));
   widget_1->ForwardMouseEvent(CreateMouseEvent(WebInputEvent::Type::kMouseUp));
@@ -560,7 +560,7 @@
 
   // The second tab's counts are independent of the other's.
   content::RenderWidgetHost* widget_2 =
-      test_contents_2->GetMainFrame()->GetRenderViewHost()->GetWidget();
+      test_contents_2->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
   widget_2->ForwardMouseEvent(
       CreateMouseEvent(WebInputEvent::Type::kMouseMove));
   expected_metrics_2[TabManager_TabMetrics::kMouseEventCountName] = 1;
@@ -592,7 +592,8 @@
   // After a navigation, test that the counts are reset.
   WebContentsTester::For(test_contents_1)->NavigateAndCommit(TestUrls()[2]);
   // The widget may have been invalidated by the navigation.
-  widget_1 = test_contents_1->GetMainFrame()->GetRenderViewHost()->GetWidget();
+  widget_1 =
+      test_contents_1->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
   widget_1->ForwardMouseEvent(
       CreateMouseEvent(WebInputEvent::Type::kMouseMove));
   expected_metrics_1[TabManager_TabMetrics::kMouseEventCountName] = 1;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
index 9ac8f2f..1efd17b 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -273,7 +273,7 @@
 
 base::ProcessHandle TabLifecycleUnitSource::TabLifecycleUnit::GetProcessHandle()
     const {
-  content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
   if (!main_frame)
     return base::ProcessHandle();
   content::RenderProcessHost* process = main_frame->GetProcess();
@@ -503,7 +503,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
   if (!fast_shutdown_success &&
       discard_reason == LifecycleUnitDiscardReason::URGENT) {
-    content::RenderFrameHost* main_frame = old_contents->GetMainFrame();
+    content::RenderFrameHost* main_frame = old_contents->GetPrimaryMainFrame();
     // We avoid fast shutdown on tabs with beforeunload handlers on the main
     // frame, as that is often an indication of unsaved user state.
     DCHECK(main_frame);
@@ -611,7 +611,7 @@
 
 content::RenderProcessHost*
 TabLifecycleUnitSource::TabLifecycleUnit::GetRenderProcessHost() const {
-  return web_contents()->GetMainFrame()->GetProcess();
+  return web_contents()->GetPrimaryMainFrame()->GetProcess();
 }
 
 void TabLifecycleUnitSource::TabLifecycleUnit::OnLifecycleUnitStateChanged(
diff --git a/chrome/browser/resource_coordinator/tab_load_tracker_unittest.cc b/chrome/browser/resource_coordinator/tab_load_tracker_unittest.cc
index 8dac58b..7e8ace2 100644
--- a/chrome/browser/resource_coordinator/tab_load_tracker_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_load_tracker_unittest.cc
@@ -306,7 +306,7 @@
                                    LoadingState::UNLOADED));
   content::MockRenderProcessHost* rph =
       static_cast<content::MockRenderProcessHost*>(
-          contents1()->GetMainFrame()->GetProcess());
+          contents1()->GetPrimaryMainFrame()->GetProcess());
   rph->SimulateCrash();
   if (use_non_ui_tabs) {
     EXPECT_TAB_COUNTS(3, 1, 0, 2);
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
index 4e4096c1..a26df4a 100644
--- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -595,8 +595,8 @@
   content::RenderProcessHost::SetMaxRendererProcessCount(1);
   OpenTwoTabs(embedded_test_server()->GetURL("a.com", "/title1.html"),
               embedded_test_server()->GetURL("a.com", "/title2.html"));
-  EXPECT_EQ(tsm()->GetWebContentsAt(0)->GetMainFrame()->GetProcess(),
-            tsm()->GetWebContentsAt(1)->GetMainFrame()->GetProcess());
+  EXPECT_EQ(tsm()->GetWebContentsAt(0)->GetPrimaryMainFrame()->GetProcess(),
+            tsm()->GetWebContentsAt(1)->GetPrimaryMainFrame()->GetProcess());
 
   // Advance time so everything is urgent discardable.
   test_clock_.Advance(kBackgroundUrgentProtectionTime);
@@ -724,7 +724,7 @@
 
   // The renderer process should be alive at this point.
   content::RenderProcessHost* process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   ASSERT_TRUE(process);
   EXPECT_TRUE(process->IsInitializedAndNotDead());
   EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());
@@ -737,13 +737,13 @@
   EXPECT_NE(new_web_contents, web_contents);
   web_contents = new_web_contents;
   content::RenderProcessHost* new_process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_NE(new_process, process);
   EXPECT_NE(new_process->GetID(), renderer_id);
   process = new_process;
 
   // The renderer process should be dead after a discard.
-  EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
+  EXPECT_EQ(process, web_contents->GetPrimaryMainFrame()->GetProcess());
   EXPECT_FALSE(process->IsInitializedAndNotDead());
   EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());
 
@@ -752,7 +752,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page));
 
   // Reload should mean that the renderer process is alive now.
-  EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
+  EXPECT_EQ(process, web_contents->GetPrimaryMainFrame()->GetProcess());
   EXPECT_TRUE(process->IsInitializedAndNotDead());
   EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());
 }
@@ -771,7 +771,7 @@
 
   // Grab the original frames.
   content::WebContents* contents = tsm()->GetActiveWebContents();
-  content::RenderFrameHost* main_frame = contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(child_frame);
 
@@ -808,7 +808,7 @@
 
   // Re-assign pointers after discarding, as they've changed.
   contents = tsm()->GetActiveWebContents();
-  main_frame = contents->GetMainFrame();
+  main_frame = contents->GetPrimaryMainFrame();
   child_frame = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(child_frame);
 
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
index d304bc39..9c26f6c 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
@@ -281,7 +281,7 @@
     return;
 
   base::ProcessHandle pid =
-      contents->GetMainFrame()->GetProcess()->GetProcess().Handle();
+      contents->GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle();
   AdjustFocusedTabScore(pid);
 }
 
diff --git a/chrome/browser/resource_coordinator/tab_memory_metrics_reporter.cc b/chrome/browser/resource_coordinator/tab_memory_metrics_reporter.cc
index 8a5c2e2c..3f4977a 100644
--- a/chrome/browser/resource_coordinator/tab_memory_metrics_reporter.cc
+++ b/chrome/browser/resource_coordinator/tab_memory_metrics_reporter.cc
@@ -144,7 +144,7 @@
 bool TabMemoryMetricsReporter::EmitMemoryMetricsAfterPageLoaded(
     const TabMemoryMetricsReporter::WebContentsData& content_data) {
   content::RenderFrameHost* render_frame_host =
-      content_data.web_contents->GetMainFrame();
+      content_data.web_contents->GetPrimaryMainFrame();
   if (!render_frame_host)
     return false;
 
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.cc b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
index ddebb10..c84d06f 100644
--- a/chrome/browser/resource_coordinator/tab_metrics_logger.cc
+++ b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
@@ -90,7 +90,7 @@
 void PopulateTabFeaturesFromWebContents(content::WebContents* web_contents,
                                         tab_ranker::TabFeatures* tab_features) {
   tab_features->has_before_unload_handler =
-      web_contents->GetMainFrame()->GetSuddenTerminationDisablerState(
+      web_contents->GetPrimaryMainFrame()->GetSuddenTerminationDisablerState(
           blink::mojom::SuddenTerminationDisablerType::kBeforeUnloadHandler);
   tab_features->has_form_entry =
       FormInteractionTabHelper::FromWebContents(web_contents)
diff --git a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
index ca31de4..3b0a3d6a 100644
--- a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
-
 /**
  * @fileoverview A helper object used from the google assistant section
  * to interact with the browser.
@@ -21,8 +19,21 @@
   syncVoiceModelStatus() {}
 }
 
+/** @type {?GoogleAssistantBrowserProxy} */
+let instance = null;
+
 /** @implements {GoogleAssistantBrowserProxy} */
 export class GoogleAssistantBrowserProxyImpl {
+  /** @return {!GoogleAssistantBrowserProxy} */
+  static getInstance() {
+    return instance || (instance = new GoogleAssistantBrowserProxyImpl());
+  }
+
+  /** @param {!GoogleAssistantBrowserProxy} obj */
+  static setInstance(obj) {
+    instance = obj;
+  }
+
   /** @override */
   showGoogleAssistantSettings() {
     chrome.send('showGoogleAssistantSettings');
@@ -38,7 +49,3 @@
     chrome.send('syncVoiceModelStatus');
   }
 }
-
-// The singleton instance_ is replaced with a test version of this wrapper
-// during testing.
-addSingletonGetter(GoogleAssistantBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
index 7694cdf06..cf7ac46d 100644
--- a/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
@@ -3,6 +3,33 @@
 // found in the LICENSE file.
 
 /**
+ * @fileoverview 'settings-google-assistant-page' is the settings page
+ * containing Google Assistant settings.
+ */
+import '//resources/cr_elements/cr_link_row/cr_link_row.js';
+import '//resources/cr_elements/md_select_css.m.js';
+import '//resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
+import '../../controls/controlled_button.js';
+import '../../controls/settings_toggle_button.js';
+import '../../prefs/prefs.js';
+import '../../prefs/pref_util.js';
+import '../../settings_shared_css.js';
+
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
+import {loadTimeData} from '//resources/js/load_time_data.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 {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 {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
+
+import {GoogleAssistantBrowserProxy, GoogleAssistantBrowserProxyImpl} from './google_assistant_browser_proxy.js';
+
+/**
  * The types of Hotword enable status without Dsp support.
  * @enum {number}
  */
@@ -35,140 +62,138 @@
 };
 
 /**
- * @fileoverview 'settings-google-assistant-page' is the settings page
- * containing Google Assistant settings.
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {I18nBehaviorInterface}
+ * @implements {PrefsBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
  */
-import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+const SettingsGoogleAssistantPageElementBase = mixinBehaviors(
+    [
+      DeepLinkingBehavior, I18nBehavior, PrefsBehavior, RouteObserverBehavior,
+      WebUIListenerBehavior
+    ],
+    PolymerElement);
 
-import '//resources/cr_elements/cr_link_row/cr_link_row.js';
-import '//resources/cr_elements/md_select_css.m.js';
-import '//resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
-import {sendWithPromise, removeWebUIListener, addWebUIListener, WebUIListener} from '//resources/js/cr.m.js';
-import {I18nBehavior} 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 '../../controls/controlled_button.js';
-import '../../controls/settings_toggle_button.js';
-import '../../prefs/prefs.js';
-import {PrefsBehavior} from '../prefs_behavior.js';
-import '../../prefs/pref_util.js';
-import {Router, Route} from '../../router.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
-import '../../settings_shared_css.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
-import {recordSettingChange} from '../metrics_recorder.js';
-import {routes} from '../os_route.js';
-import {GoogleAssistantBrowserProxy, GoogleAssistantBrowserProxyImpl} from './google_assistant_browser_proxy.js';
+/** @polymer */
+class SettingsGoogleAssistantPageElement extends
+    SettingsGoogleAssistantPageElementBase {
+  static get is() {
+    return 'settings-google-assistant-page';
+  }
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-google-assistant-page',
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  behaviors: [
-    DeepLinkingBehavior, I18nBehavior, PrefsBehavior, RouteObserverBehavior,
-    WebUIListenerBehavior
-  ],
-
-  properties: {
-    /** @private */
-    shouldShowVoiceMatchSettings_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /** @private */
-    hotwordDspAvailable_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('hotwordDspAvailable');
+  static get properties() {
+    return {
+      /** @private */
+      shouldShowVoiceMatchSettings_: {
+        type: Boolean,
+        value: false,
       },
-    },
 
-    /** @private */
-    hotwordDropdownList_: {
-      type: Array,
-      value() {
-        return [
-          {
-            name: loadTimeData.getString(
-                'googleAssistantEnableHotwordWithoutDspRecommended'),
-            value: DspHotwordState.DEFAULT_ON
-          },
-          {
-            name: loadTimeData.getString(
-                'googleAssistantEnableHotwordWithoutDspAlwaysOn'),
-            value: DspHotwordState.ALWAYS_ON
-          },
-          {
-            name: loadTimeData.getString(
-                'googleAssistantEnableHotwordWithoutDspOff'),
-            value: DspHotwordState.OFF
-          }
-        ];
+      /** @private */
+      hotwordDspAvailable_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('hotwordDspAvailable');
+        },
       },
-    },
 
-    /** @private */
-    hotwordEnforced_: {
-      type: Boolean,
-      value: false,
-    },
+      /** @private */
+      hotwordDropdownList_: {
+        type: Array,
+        value() {
+          return [
+            {
+              name: loadTimeData.getString(
+                  'googleAssistantEnableHotwordWithoutDspRecommended'),
+              value: DspHotwordState.DEFAULT_ON
+            },
+            {
+              name: loadTimeData.getString(
+                  'googleAssistantEnableHotwordWithoutDspAlwaysOn'),
+              value: DspHotwordState.ALWAYS_ON
+            },
+            {
+              name: loadTimeData.getString(
+                  'googleAssistantEnableHotwordWithoutDspOff'),
+              value: DspHotwordState.OFF
+            }
+          ];
+        },
+      },
 
-    /** @private */
-    hotwordEnforcedForChild_: {
-      type: Boolean,
-      value: false,
-    },
+      /** @private */
+      hotwordEnforced_: {
+        type: Boolean,
+        value: false,
+      },
 
-    /** @private {DspHotwordState} */
-    dspHotwordState_: Number,
+      /** @private */
+      hotwordEnforcedForChild_: {
+        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.kAssistantOnOff,
-        chromeos.settings.mojom.Setting.kAssistantRelatedInfo,
-        chromeos.settings.mojom.Setting.kAssistantOkGoogle,
-        chromeos.settings.mojom.Setting.kAssistantNotifications,
-        chromeos.settings.mojom.Setting.kAssistantVoiceInput,
-        chromeos.settings.mojom.Setting.kTrainAssistantVoiceModel,
-      ]),
-    },
-  },
+      /** @private {DspHotwordState} */
+      dspHotwordState_: Number,
 
-  observers: [
-    'onPrefsChanged_(' +
-        'prefs.settings.voice_interaction.hotword.enabled.value, ' +
-        'prefs.settings.voice_interaction.hotword.always_on.value, ' +
-        'prefs.settings.voice_interaction.activity_control.consent_status' +
-        '.value, ' +
-        'prefs.settings.assistant.disabled_by_policy.value)',
-  ],
+      /**
+       * 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.kAssistantOnOff,
+          chromeos.settings.mojom.Setting.kAssistantRelatedInfo,
+          chromeos.settings.mojom.Setting.kAssistantOkGoogle,
+          chromeos.settings.mojom.Setting.kAssistantNotifications,
+          chromeos.settings.mojom.Setting.kAssistantVoiceInput,
+          chromeos.settings.mojom.Setting.kTrainAssistantVoiceModel,
+        ]),
+      },
+    };
+  }
 
-  /** @private {?GoogleAssistantBrowserProxy} */
-  browserProxy_: null,
+  static get observers() {
+    return [
+      'onPrefsChanged_(' +
+          'prefs.settings.voice_interaction.hotword.enabled.value, ' +
+          'prefs.settings.voice_interaction.hotword.always_on.value, ' +
+          'prefs.settings.voice_interaction.activity_control.consent_status' +
+          '.value, ' +
+          'prefs.settings.assistant.disabled_by_policy.value)',
+    ];
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {!GoogleAssistantBrowserProxy} */
     this.browserProxy_ = GoogleAssistantBrowserProxyImpl.getInstance();
-  },
+  }
 
   /** @override */
   ready() {
+    super.ready();
+
     this.addWebUIListener('hotwordDeviceUpdated', (hasHotword) => {
       this.hotwordDspAvailable_ = hasHotword;
     });
 
     chrome.send('initializeGoogleAssistantPage');
-  },
+  }
 
   /**
    * @param {!Route} route
-   * @param {!Route} oldRoute
+   * @param {!Route=} oldRoute
    */
   currentRouteChanged(route, oldRoute) {
     // Does not apply to this page.
@@ -177,7 +202,7 @@
     }
 
     this.attemptDeepLink();
-  },
+  }
 
   /**
    * @param {boolean} toggleValue
@@ -187,30 +212,30 @@
   getAssistantOnOffLabel_(toggleValue) {
     return this.i18n(
         toggleValue ? 'searchGoogleAssistantOn' : 'searchGoogleAssistantOff');
-  },
+  }
 
   /** @private */
   onGoogleAssistantSettingsTapped_() {
     this.browserProxy_.showGoogleAssistantSettings();
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onRetrainVoiceModelTapped_() {
     this.browserProxy_.retrainAssistantVoiceModel();
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onEnableHotwordChange_(event) {
     if (event.target.checked) {
       this.browserProxy_.syncVoiceModelStatus();
     }
-  },
+  }
 
   /** @private */
   onDspHotwordStateChange_() {
-    switch (Number(this.$$('#dsp-hotword-state').value)) {
+    switch (Number(this.shadowRoot.querySelector('#dsp-hotword-state').value)) {
       case DspHotwordState.DEFAULT_ON:
         this.setPrefValue('settings.voice_interaction.hotword.enabled', true);
         this.setPrefValue(
@@ -230,7 +255,7 @@
       default:
         console.error('Invalid Dsp hotword settings state');
     }
-  },
+  }
 
   /**
    * @param {number} state
@@ -239,7 +264,7 @@
    */
   isDspHotwordStateMatch_(state) {
     return state === this.dspHotwordState_;
-  },
+  }
 
   /** @private */
   onPrefsChanged_() {
@@ -263,7 +288,7 @@
     this.hotwordEnforcedForChild_ = this.hotwordEnforced_ &&
         hotwordEnabled.controlledBy ===
             chrome.settingsPrivate.ControlledBy.CHILD_RESTRICTION;
-  },
+  }
 
   /** @private */
   refreshDspHotwordState_() {
@@ -276,8 +301,12 @@
       this.dspHotwordState_ = DspHotwordState.DEFAULT_ON;
     }
 
-    if (this.$$('#dsp-hotword-state')) {
-      this.$$('#dsp-hotword-state').value = this.dspHotwordState_;
+    if (this.shadowRoot.querySelector('#dsp-hotword-state')) {
+      this.shadowRoot.querySelector('#dsp-hotword-state').value =
+          this.dspHotwordState_;
     }
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsGoogleAssistantPageElement.is, SettingsGoogleAssistantPageElement);
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
index 0756ba4..2c074ae 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
@@ -8,112 +8,136 @@
  * list, add and delete Kerberos Accounts.
  */
 
-'use strict';
-
-import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import '//resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import '//resources/cr_elements/cr_button/cr_button.m.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
-import '//resources/cr_elements/cr_toast/cr_toast.js';
-import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
-import {getImage} from '//resources/js/icon.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
-import '//resources/polymer/v3_0/iron-media-query/iron-media-query.js';
-import {loadTimeData} from '../../i18n_setup.js';
-import {Account} from '../os_people_page/account_manager_browser_proxy.js';
-import {Router, Route} from '../../router.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
+import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
+import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
+import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js';
 import '../../settings_shared_css.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
-import {recordSettingChange} from '../metrics_recorder.js';
-import {routes} from '../os_route.js';
-import {KerberosAccount, KerberosAccountsBrowserProxyImpl, KerberosAccountsBrowserProxy, KerberosErrorType, KerberosConfigErrorCode, ValidateKerberosConfigResult} from './kerberos_accounts_browser_proxy.js';
 import './kerberos_add_account_dialog.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-kerberos-accounts',
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {getImage} from 'chrome://resources/js/icon.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-  behaviors: [
-    DeepLinkingBehavior,
-    I18nBehavior,
-    RouteObserverBehavior,
-    WebUIListenerBehavior,
-  ],
+import {loadTimeData} from '../../i18n_setup.js';
+import {Route, Router} from '../../router.js';
+import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
+import {recordSettingChange} from '../metrics_recorder.js';
+import {Account} from '../os_people_page/account_manager_browser_proxy.js';
+import {routes} from '../os_route.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-  properties: {
-    /**
-     * List of Accounts.
-     * @private {!Array<!KerberosAccount>}
-     */
-    accounts_: {
-      type: Array,
-      value() {
-        return [];
+import {KerberosAccount, KerberosAccountsBrowserProxy, KerberosAccountsBrowserProxyImpl, KerberosErrorType} from './kerberos_accounts_browser_proxy.js';
+
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {I18nBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsKerberosAccountsElementBase = mixinBehaviors(
+    [
+      DeepLinkingBehavior, I18nBehavior, RouteObserverBehavior,
+      WebUIListenerBehavior
+    ],
+    PolymerElement);
+
+/** @polymer */
+class SettingsKerberosAccountsElement extends
+    SettingsKerberosAccountsElementBase {
+  static get is() {
+    return 'settings-kerberos-accounts';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * List of Accounts.
+       * @private {!Array<!KerberosAccount>}
+       */
+      accounts_: {
+        type: Array,
+        value() {
+          return [];
+        },
       },
-    },
 
-    /**
-     * Whether dark mode is currently active.
-     * @private
-     */
-    isDarkModeActive_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /**
-     * The targeted account for menu and other operations.
-     * @private {?KerberosAccount}
-     */
-    selectedAccount_: Object,
-
-    /** @private */
-    showAddAccountDialog_: Boolean,
-
-    /** @private */
-    addAccountsAllowed_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('kerberosAddAccountsAllowed');
+      /**
+       * Whether dark mode is currently active.
+       * @private
+       */
+      isDarkModeActive_: {
+        type: Boolean,
+        value: false,
       },
-    },
 
-    /** @private */
-    accountToastText_: {
-      type: String,
-      value: '',
-    },
+      /**
+       * The targeted account for menu and other operations.
+       * @private {?KerberosAccount}
+       */
+      selectedAccount_: Object,
 
-    /**
-     * 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.kAddKerberosTicketV2,
-        chromeos.settings.mojom.Setting.kRemoveKerberosTicketV2,
-        chromeos.settings.mojom.Setting.kSetActiveKerberosTicketV2,
-      ]),
-    },
-  },
+      /** @private */
+      showAddAccountDialog_: Boolean,
 
-  /** @private {?KerberosAccountsBrowserProxy} */
-  browserProxy_: null,
+      /** @private */
+      addAccountsAllowed_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('kerberosAddAccountsAllowed');
+        },
+      },
+
+      /** @private */
+      accountToastText_: {
+        type: String,
+        value: '',
+      },
+
+      /**
+       * 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.kAddKerberosTicketV2,
+          chromeos.settings.mojom.Setting.kRemoveKerberosTicketV2,
+          chromeos.settings.mojom.Setting.kSetActiveKerberosTicketV2,
+        ]),
+      },
+
+    };
+  }
+
+  constructor() {
+    super();
+
+    /** @private {!KerberosAccountsBrowserProxy} */
+    this.browserProxy_ = KerberosAccountsBrowserProxyImpl.getInstance();
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.addWebUIListener(
         'kerberos-accounts-changed', this.refreshAccounts_.bind(this));
-  },
+  }
 
   /** @override */
   ready() {
-    this.browserProxy_ = KerberosAccountsBrowserProxyImpl.getInstance();
+    super.ready();
 
     // Grab account list and - when done - pop up the reauthentication dialog if
     // there is a kerberos_reauth param.
@@ -128,12 +152,12 @@
         this.showAddAccountDialog_ = true;
       }
     });
-  },
+  }
 
   /**
    * RouteObserverBehavior
    * @param {!Route} route
-   * @param {!Route} oldRoute
+   * @param {!Route=} oldRoute
    * @protected
    */
   currentRouteChanged(route, oldRoute) {
@@ -143,7 +167,7 @@
     }
 
     this.attemptDeepLink();
-  },
+  }
 
   /**
    * @return {string} the icon to use for the error badge.
@@ -153,7 +177,7 @@
     return this.isDarkModeActive_ ?
         'chrome://os-settings/images/error_badge_dark.svg' :
         'chrome://os-settings/images/error_badge.svg';
-  },
+  }
 
   /**
    * @param {string} iconUrl
@@ -162,7 +186,7 @@
    */
   getIconImageSet_(iconUrl) {
     return getImage(iconUrl);
-  },
+  }
 
   /**
    * @param {!Event} event
@@ -171,7 +195,7 @@
   onAddAccountClick_(event) {
     this.selectedAccount_ = null;
     this.showAddAccountDialog_ = true;
-  },
+  }
 
   /**
    * @param {!CustomEvent<!{model: !{item: !Account}}>} event
@@ -180,11 +204,12 @@
   onReauthenticationClick_(event) {
     this.selectedAccount_ = event.model.item;
     this.showAddAccountDialog_ = true;
-  },
+  }
 
   /** @private */
   onAddAccountDialogClosed_() {
-    if (this.$$('kerberos-add-account-dialog').accountWasRefreshed) {
+    if (this.shadowRoot.querySelector('kerberos-add-account-dialog')
+            .accountWasRefreshed) {
       this.showToast_('kerberosAccountsAccountRefreshedTip');
     }
 
@@ -192,7 +217,7 @@
 
     // In case it was opened by the 'Refresh now' action menu.
     this.closeActionMenu_();
-  },
+  }
 
   /**
    * @return {!Promise}
@@ -202,7 +227,7 @@
     return this.browserProxy_.getAccounts().then(accounts => {
       this.accounts_ = accounts;
     });
-  },
+  }
 
   /**
    * Opens the Account actions menu.
@@ -212,18 +237,19 @@
    */
   onAccountActionsMenuButtonClick_(event) {
     this.selectedAccount_ = event.model.item;
-    /** @type {!CrActionMenuElement} */ (this.$$('cr-action-menu'))
+    /** @type {!CrActionMenuElement} */ (
+        this.shadowRoot.querySelector('cr-action-menu'))
         .showAt(event.target);
-  },
+  }
 
   /**
    * Closes action menu and resets action menu model.
    * @private
    */
   closeActionMenu_() {
-    this.$$('cr-action-menu').close();
+    this.shadowRoot.querySelector('cr-action-menu').close();
     this.selectedAccount_ = null;
-  },
+  }
 
   /**
    * Removes |this.selectedAccount_|.
@@ -242,7 +268,7 @@
         });
     recordSettingChange();
     this.closeActionMenu_();
-  },
+  }
 
   /**
    * Sets |this.selectedAccount_| as active Kerberos account.
@@ -253,7 +279,7 @@
         /** @type {!KerberosAccount} */ (this.selectedAccount_));
     recordSettingChange();
     this.closeActionMenu_();
-  },
+  }
 
   /**
    * Opens the reauth dialog for |this.selectedAccount_|.
@@ -261,7 +287,7 @@
    */
   onRefreshNowClick_() {
     this.showAddAccountDialog_ = true;
-  },
+  }
 
   /**
    * Pops up a toast with localized text |label|.
@@ -270,6 +296,9 @@
    */
   showToast_(label) {
     this.accountToastText_ = this.i18n(label);
-    this.$$('#account-toast').show();
+    this.shadowRoot.querySelector('#account-toast').show();
   }
-});
+}
+
+customElements.define(
+    SettingsKerberosAccountsElement.is, SettingsKerberosAccountsElement);
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.js b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.js
index 3801c82..518082e 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.js
@@ -2,29 +2,27 @@
 // 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, sendWithPromise} from 'chrome://resources/js/cr.m.js';
-// clang-format on
-
 /**
  * @fileoverview A helper object used from the "Kerberos Accounts" subsection of
  * the "Kerberos" section of Settings, to interact with the browser. Chrome OS
  * only.
  */
 
-  /**
-   * Information for a Chrome OS Kerberos account.
-   * @typedef {{
-   *   principalName: string,
-   *   config: string,
-   *   isSignedIn: boolean,
-   *   isActive: boolean,
-   *   isManaged: boolean,
-   *   passwordWasRemembered: boolean,
-   *   pic: string,
-   *   validForDuration: string
-   * }}
-   */
+import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
+
+/**
+ * Information for a Chrome OS Kerberos account.
+ * @typedef {{
+ *   principalName: string,
+ *   config: string,
+ *   isSignedIn: boolean,
+ *   isActive: boolean,
+ *   isManaged: boolean,
+ *   passwordWasRemembered: boolean,
+ *   pic: string,
+ *   validForDuration: string
+ * }}
+ */
 export let KerberosAccount;
 
 /**
@@ -131,10 +129,23 @@
   setAsActiveAccount(account) {}
 }
 
+/** @type {?KerberosAccountsBrowserProxy} */
+let instance = null;
+
 /**
  * @implements {KerberosAccountsBrowserProxy}
  */
 export class KerberosAccountsBrowserProxyImpl {
+  /** @return {!KerberosAccountsBrowserProxy} */
+  static getInstance() {
+    return instance || (instance = new KerberosAccountsBrowserProxyImpl());
+  }
+
+  /** @param {!KerberosAccountsBrowserProxy} obj */
+  static setInstance(obj) {
+    instance = obj;
+  }
+
   /** @override */
   getAccounts() {
     return sendWithPromise('getKerberosAccounts');
@@ -162,5 +173,3 @@
     chrome.send('setAsActiveKerberosAccount', [account.principalName]);
   }
 }
-
-addSingletonGetter(KerberosAccountsBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_add_account_dialog.js b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_add_account_dialog.js
index 013fb6e..308cd0e 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_add_account_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_add_account_dialog.js
@@ -7,166 +7,182 @@
  * 'kerberos-add-account-dialog' is an element to add Kerberos accounts.
  */
 
-import '//resources/cr_elements/cr_button/cr_button.m.js';
-import '//resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import '//resources/cr_elements/cr_input/cr_input.m.js';
-import '//resources/cr_elements/icons.m.js';
-import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
-import '//resources/cr_elements/shared_vars_css.m.js';
-import '//resources/js/action_link.js';
-import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/js/action_link.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../../controls/settings_textarea.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 {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 {assert, assertNotReached} from 'chrome://resources/js/assert.m.js';
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {flush, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {recordSettingChange} from '../metrics_recorder.js';
 
 import {KerberosAccount, KerberosAccountsBrowserProxy, KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType, ValidateKerberosConfigResult} from './kerberos_accounts_browser_proxy.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'kerberos-add-account-dialog',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ */
+const KerberosAddAccountDialogElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement);
 
-  behaviors: [I18nBehavior],
+/** @polymer */
+class KerberosAddAccountDialogElement extends
+    KerberosAddAccountDialogElementBase {
+  static get is() {
+    return 'kerberos-add-account-dialog';
+  }
 
-  properties: {
-    /**
-     * If set, some fields are preset from this account (like username or
-     * whether to remember the password).
-     * @type {?KerberosAccount}
-     */
-    presetAccount: Object,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /**
-     * Whether an existing |presetAccount| was successfully authenticated.
-     * Always false if |presetAccount| is null (new accounts).
-     */
-    accountWasRefreshed: {
-      type: Boolean,
-      value: false,
-    },
+  static get properties() {
+    return {
+      /**
+       * If set, some fields are preset from this account (like username or
+       * whether to remember the password).
+       * @type {?KerberosAccount}
+       */
+      presetAccount: Object,
 
-    /** @private */
-    username_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    password_: {
-      type: String,
-      value: '',
-    },
-
-    /**
-     * Current configuration in the Advanced Config dialog. Propagates to
-     * |config| only if 'Save' button is pressed.
-     * @private {string}
-     */
-    editableConfig_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    rememberPassword_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /** @private */
-    generalErrorText_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    usernameErrorText_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    passwordErrorText_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    configErrorText_: {
-      type: String,
-      value: '',
-    },
-
-    /** @private */
-    inProgress_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /** @private */
-    isManaged_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /** @private */
-    showAdvancedConfig_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /**
-     * Whether the remember password options is allowed by policy.
-     * @private {boolean}
-     */
-    rememberPasswordEnabled_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('kerberosRememberPasswordEnabled');
+      /**
+       * Whether an existing |presetAccount| was successfully authenticated.
+       * Always false if |presetAccount| is null (new accounts).
+       */
+      accountWasRefreshed: {
+        type: Boolean,
+        value: false,
       },
-    },
 
-    /**
-     * Whether the user is in guest mode.
-     * @private {boolean}
-     */
-    isGuestMode_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('isGuest');
+      /** @private */
+      username_: {
+        type: String,
+        value: '',
       },
-    },
-  },
 
-  /** @private {boolean} */
-  useRememberedPassword_: false,
+      /** @private */
+      password_: {
+        type: String,
+        value: '',
+      },
 
-  /** @private {string} */
-  config_: '',
+      /**
+       * Current configuration in the Advanced Config dialog. Propagates to
+       * |config| only if 'Save' button is pressed.
+       * @private {string}
+       */
+      editableConfig_: {
+        type: String,
+        value: '',
+      },
 
-  /** @private {string} */
-  title_: '',
+      /** @private */
+      rememberPassword_: {
+        type: Boolean,
+        value: false,
+      },
 
-  /** @private {string} */
-  actionButtonLabel_: '',
+      /** @private */
+      generalErrorText_: {
+        type: String,
+        value: '',
+      },
 
-  /** @private {?KerberosAccountsBrowserProxy} */
-  browserProxy_: null,
+      /** @private */
+      usernameErrorText_: {
+        type: String,
+        value: '',
+      },
+
+      /** @private */
+      passwordErrorText_: {
+        type: String,
+        value: '',
+      },
+
+      /** @private */
+      configErrorText_: {
+        type: String,
+        value: '',
+      },
+
+      /** @private */
+      inProgress_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /** @private */
+      isManaged_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /** @private */
+      showAdvancedConfig_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /**
+       * Whether the remember password options is allowed by policy.
+       * @private {boolean}
+       */
+      rememberPasswordEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('kerberosRememberPasswordEnabled');
+        },
+      },
+
+      /**
+       * Whether the user is in guest mode.
+       * @private {boolean}
+       */
+      isGuestMode_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isGuest');
+        },
+      },
+    };
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {boolean} */
+    this.useRememberedPassword_ = false;
+
+    /** @private {string} */
+    this.config_ = '';
+
+    /** @private {string} */
+    this.title_ = '';
+
+    /** @private {string} */
+    this.actionButtonLabel_ = '';
+
+    /** @private {!KerberosAccountsBrowserProxy} */
     this.browserProxy_ = KerberosAccountsBrowserProxyImpl.getInstance();
-  },
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.$.addDialog.showModal();
 
     if (this.presetAccount) {
@@ -204,12 +220,12 @@
       // Set a default configuration.
       this.config_ = loadTimeData.getString('defaultKerberosConfig');
     }
-  },
+  }
 
   /** @private */
   onCancel_() {
     this.$.addDialog.cancel();
-  },
+  }
 
   /** @private */
   onAdd_() {
@@ -245,14 +261,14 @@
           this.updateErrorMessages_(error);
         });
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onPasswordInput_() {
     // On first input, don't reuse the remembered password, but submit the
     // changed one.
     this.useRememberedPassword_ = false;
-  },
+  }
 
   /** @private */
   onAdvancedConfigClick_() {
@@ -260,15 +276,15 @@
     this.editableConfig_ = this.config_;
     this.showAdvancedConfig_ = true;
     flush();
-    this.$$('#advancedConfigDialog').showModal();
-  },
+    this.shadowRoot.querySelector('#advancedConfigDialog').showModal();
+  }
 
   /** @private */
   onAdvancedConfigCancel_() {
     this.configErrorText_ = '';
     this.showAdvancedConfig_ = false;
-    this.$$('#advancedConfigDialog').cancel();
-  },
+    this.shadowRoot.querySelector('#advancedConfigDialog').cancel();
+  }
 
   /** @private */
   onAdvancedConfigSave_() {
@@ -283,7 +299,7 @@
         this.showAdvancedConfig_ = false;
         this.config_ = this.editableConfig_;
         this.configErrorText_ = '';
-        this.$$('#advancedConfigDialog').close();
+        this.shadowRoot.querySelector('#advancedConfigDialog').close();
         return;
       }
 
@@ -291,7 +307,7 @@
       this.updateConfigErrorMessage_(result);
     });
     recordSettingChange();
-  },
+  }
 
   onAdvancedConfigClose_(event) {
     // Note: 'Esc' doesn't trigger onAdvancedConfigCancel_() and some tests
@@ -302,7 +318,7 @@
     // Since this is a sub-dialog, prevent event from bubbling up. Otherwise,
     // it might cause the add-dialog to be closed.
     event.stopPropagation();
-  },
+  }
 
   /**
    * @param {!KerberosErrorType} error Current error enum
@@ -348,7 +364,7 @@
         this.generalErrorText_ =
             this.i18n('kerberosErrorGeneral', error.toString());
     }
-  },
+  }
 
   /**
    * @param {!ValidateKerberosConfigResult} result Result from a
@@ -371,7 +387,9 @@
 
     // Don't fall for the classical blunder 0 == false.
     if (result.errorInfo.lineIndex !== undefined) {
-      const textArea = this.$$('#config').shadowRoot.querySelector('#input');
+      const textArea =
+          this.shadowRoot.querySelector('#config').shadowRoot.querySelector(
+              '#input');
       errorLine = this.selectAndScrollTo_(textArea, result.errorInfo.lineIndex);
     }
 
@@ -379,7 +397,7 @@
     assert(result.errorInfo.code !== KerberosConfigErrorCode.kNone);
     this.configErrorText_ =
         this.getConfigErrorString_(result.errorInfo.code, errorLine);
-  },
+  }
 
   /**
    * @param {!KerberosConfigErrorCode} code Error code
@@ -412,7 +430,7 @@
       default:
         assertNotReached();
     }
-  },
+  }
 
   /**
    * Selects a line in a text area and scrolls to it.
@@ -446,7 +464,7 @@
     textArea.scrollTop = lineHeight * firstLine;
 
     return lines[lineIndex];
-  },
+  }
 
   /**
    * Whether an error element should be shown.
@@ -458,4 +476,7 @@
   showError_(errorText) {
     return !!errorText;
   }
-});
+}
+
+customElements.define(
+    KerberosAddAccountDialogElement.is, KerberosAddAccountDialogElement);
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_page.js b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_page.js
index a175902..5356e40 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_page.js
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_page.js
@@ -7,52 +7,64 @@
  * 'settings-kerberos-page' is the settings page containing Kerberos Tickets
  * settings.
  */
-import '//resources/cr_elements/cr_link_row/cr_link_row.js';
-import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
-import '//resources/cr_elements/shared_vars_css.m.js';
-import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
+import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import '../../settings_page/settings_animated_pages.js';
 import '../../settings_page/settings_subpage.js';
 import '../../settings_shared_css.js';
 import './kerberos_accounts.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
-import {HTMLEscape, listenOnce} from '//resources/js/util.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 'chrome://resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Route, Router} from '../../router.js';
+import {Router} from '../../router.js';
 import {routes} from '../os_route.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-kerberos-page',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsKerberosPageElementBase =
+    mixinBehaviors([I18nBehavior, WebUIListenerBehavior], PolymerElement);
 
-  behaviors: [
-    I18nBehavior,
-    WebUIListenerBehavior,
-  ],
+/** @polymer */
+class SettingsKerberosPageElement extends SettingsKerberosPageElementBase {
+  static get is() {
+    return 'settings-kerberos-page';
+  }
 
-  properties: {
-    /** @private {!Map<string, string>} */
-    focusConfig_: {
-      type: Object,
-      value() {
-        const map = new Map();
-        if (routes.KERBEROS_ACCOUNTS_V2) {
-          map.set(
-              routes.KERBEROS_ACCOUNTS_V2.path,
-              '#kerberos-accounts-subpage-trigger');
-        }
-        return map;
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /** @private {!Map<string, string>} */
+      focusConfig_: {
+        type: Object,
+        value() {
+          const map = new Map();
+          if (routes.KERBEROS_ACCOUNTS_V2) {
+            map.set(
+                routes.KERBEROS_ACCOUNTS_V2.path,
+                '#kerberos-accounts-subpage-trigger');
+          }
+          return map;
+        },
       },
-    },
-  },
+    };
+  }
 
   /** @private */
   onKerberosAccountsTap_() {
     Router.getInstance().navigateTo(routes.KERBEROS_ACCOUNTS_V2);
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsKerberosPageElement.is, SettingsKerberosPageElement);
diff --git a/chrome/browser/resources/webui_gallery/BUILD.gn b/chrome/browser/resources/webui_gallery/BUILD.gn
index 7cc74663..e6e105d 100644
--- a/chrome/browser/resources/webui_gallery/BUILD.gn
+++ b/chrome/browser/resources/webui_gallery/BUILD.gn
@@ -29,6 +29,7 @@
   grd_prefix = "webui_gallery"
   out_grd = "$target_gen_dir/resources.grd"
   input_files = [
+    "demos/demo.css",
     "demos/cr_button_demo.html",
     "demos/cr_checkbox_demo.html",
     "webui_gallery.html",
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html
index d2e07a4b..edf7260 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html
+++ b/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html
@@ -3,20 +3,34 @@
   <head>
     <meta charset="utf-8">
     <title>cr-button demo</title>
+    <link rel="stylesheet" href="demo.css">
     <style>
-      html,
-      body {
-        height: 100%;
-        overflow: hidden;
-        width: 100%;
-      }
-
-      body {
-        margin: 0;
+      cr-button[circle-ripple] {
+        height: 60px;
+        width: 60px;
       }
     </style>
-  </head>
   <body>
-    Demo content will be added here
+    <h1>cr-button</h1>
+    <div class="demos">
+      <cr-button>Primary button</cr-button>
+      <cr-button class="action-button">Action button</cr-button>
+      <cr-button disabled>Disabled primary button</cr-button>
+      <cr-button disabled class="action-button">
+        Disabled action button
+      </cr-button>
+      <div class="flex">
+        <cr-button class="cancel-button">Cancel</cr-button>
+        <cr-button class="action-button">Confirm</cr-button>
+      </div>
+      <div class="row">
+        <cr-button circle-ripple>1</cr-button>
+        <cr-button circle-ripple>2</cr-button>
+        <cr-button circle-ripple>3</cr-button>
+      </div>
+    </div>
+
+    <script src="chrome://resources/cr_elements/cr_button/cr_button.m.js"
+        type="module"></script>
   </body>
 </html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html
index 55660ca..238361d 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html
+++ b/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html
@@ -3,20 +3,17 @@
   <head>
     <meta charset="utf-8">
     <title>cr-checkbox demo</title>
-    <style>
-      html,
-      body {
-        height: 100%;
-        overflow: hidden;
-        width: 100%;
-      }
-
-      body {
-        margin: 0;
-      }
-    </style>
-  </head>
+    <link rel="stylesheet" href="demo.css">
   <body>
-    Demo content will be added here
+    <h1>cr-checkbox</h1>
+    <div class="demos">
+      <cr-checkbox>Checkbox</cr-checkbox>
+      <cr-checkbox checked>Checkbox</cr-checkbox>
+      <cr-checkbox disabled>Disabled checkbox</cr-checkbox>
+      <cr-checkbox checked disabled>Disabled checked checkbox</cr-checkbox>
+    </div>
+
+    <script src="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js"
+        type="module"></script>
   </body>
 </html>
diff --git a/chrome/browser/resources/webui_gallery/demos/demo.css b/chrome/browser/resources/webui_gallery/demos/demo.css
new file mode 100644
index 0000000..b540b50b
--- /dev/null
+++ b/chrome/browser/resources/webui_gallery/demos/demo.css
@@ -0,0 +1,32 @@
+/* Copyright 2022 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+@import 'chrome://resources/css/text_defaults_md.css';
+
+body {
+  margin: 0;
+  padding: 16px;
+}
+
+h1 {
+  font-size: 1.5em;
+  margin: 0;
+  margin-block-end: 16px;
+}
+
+.demos {
+  align-items: flex-start;
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+}
+
+.row {
+  display: flex;
+  gap: 16px;
+}
+
+.flex {
+  display: flex;
+}
\ No newline at end of file
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index cea3604..547b3dc 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -378,7 +378,7 @@
       prefs::kSafeBrowsingUnhandledGaiaPasswordReuses);
   return unhandled_sync_password_reuses
              ? (unhandled_sync_password_reuses->FindKey(
-                    web_contents->GetMainFrame()
+                    web_contents->GetPrimaryMainFrame()
                         ->GetLastCommittedOrigin()
                         .Serialize()) != nullptr)
              : false;
@@ -479,7 +479,9 @@
     // Since base::Value doesn't support int64_t type, we convert the navigation
     // ID to string format and store it in the preference dictionary.
     update->SetStringKey(
-        web_contents->GetMainFrame()->GetLastCommittedOrigin().Serialize(),
+        web_contents->GetPrimaryMainFrame()
+            ->GetLastCommittedOrigin()
+            .Serialize(),
         base::NumberToString(GetLastCommittedNavigationID(web_contents)));
   }
   SBThreatType threat_type;
@@ -585,7 +587,7 @@
     return;
 
   const content::GlobalRenderFrameHostId primary_main_frame_id =
-      web_contents->GetMainFrame()->GetGlobalId();
+      web_contents->GetPrimaryMainFrame()->GetGlobalId();
   security_interstitials::UnsafeResource resource;
   if (password_type.account_type() ==
       ReusedPasswordAccountType::NON_GAIA_ENTERPRISE) {
@@ -939,7 +941,8 @@
     LoginReputationClientResponse::VerdictType verdict_type,
     const std::string& verdict_token,
     WarningAction action) {
-  const Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  const Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   int64_t navigation_id =
       GetNavigationIDFromPrefsByOrigin(profile_->GetPrefs(), origin);
 
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index 0ed25c2..89089ff 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -1029,7 +1029,7 @@
   // Start a renderer-initiated navigation away from the current page. The
   // navigation should be deferred.
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
-  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
+  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
 
   // Run the navigation until it defers on the
@@ -1063,7 +1063,7 @@
   // Start a renderer-initiated navigation away from the current page. The
   // navigation should be deferred.
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
-  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
+  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
 
   // Run the navigation until it defers on the
@@ -1098,7 +1098,7 @@
   // Start a renderer-initiated navigation away from the current page. The
   // navigation should be deferred.
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
-  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
+  ASSERT_TRUE(content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
   // Run the navigation until it defers on the
   // PasswordProtectionCommitDeferringCondition.
@@ -1219,7 +1219,7 @@
                                                    kPrerenderUrl);
 
   ASSERT_TRUE(
-      content::ExecJs(GetWebContents()->GetMainFrame(),
+      content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                       content::JsReplace("location = $1", kPrerenderUrl)));
 
   // Run the navigation until it defers on the
@@ -1262,7 +1262,7 @@
   content::TestActivationManager prerender_manager(GetWebContents(),
                                                    kPrerenderUrl);
   ASSERT_TRUE(
-      content::ExecJs(GetWebContents()->GetMainFrame(),
+      content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                       content::JsReplace("location = $1", kPrerenderUrl)));
 
   // Run the navigation until it defers on the
@@ -1303,7 +1303,7 @@
                                                    kPrerenderUrl);
 
   ASSERT_TRUE(
-      content::ExecJs(GetWebContents()->GetMainFrame(),
+      content::ExecJs(GetWebContents()->GetPrimaryMainFrame(),
                       content::JsReplace("location = $1", kPrerenderUrl)));
 
   // Run the navigation until it defers on the
@@ -1390,7 +1390,7 @@
   content::TestActivationManager prerender_manager(GetWebContents(),
                                                    kURLInBFCache);
   ASSERT_TRUE(content::ExecJs(
-      GetWebContents()->GetMainFrame(),
+      GetWebContents()->GetPrimaryMainFrame(),
       content::JsReplace("window.history.back()", kURLInBFCache)));
 
   // Run the navigation until it defers on the
diff --git a/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc
index bb9b278..2ea458d4 100644
--- a/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc
+++ b/chrome/browser/safe_browsing/chrome_ui_manager_delegate.cc
@@ -68,7 +68,7 @@
 
   extensions::ExtensionHost* extension_host =
       extension_manager->GetExtensionHostForRenderFrameHost(
-          web_contents->GetMainFrame());
+          web_contents->GetPrimaryMainFrame());
   return extension_host != nullptr;
 #else
   return false;
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
index 5a49278a..788369ef 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -302,7 +302,7 @@
     // Initiate the connection to a (pretend) renderer process.
     NavigateAndCommit(GURL("about:blank"));
 
-    InitTestApi(web_contents()->GetMainFrame());
+    InitTestApi(web_contents()->GetPrimaryMainFrame());
 
     // Inject service classes.
     csd_service_ = std::make_unique<MockClientSideDetectionService>();
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc b/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc
index f2928410..0678bd2 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc
@@ -50,8 +50,10 @@
 
   base::RunLoop run_loop;
 
-  content::RenderFrameHost* rfh =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* rfh = browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame();
   mojo::Remote<mojom::PhishingDetector> phishing_detector;
   rfh->GetRemoteInterfaces()->GetInterface(
       phishing_detector.BindNewPipeAndPassReceiver());
diff --git a/chrome/browser/safe_browsing/delayed_warning_navigation_throttle.cc b/chrome/browser/safe_browsing/delayed_warning_navigation_throttle.cc
index 35b1577d..19b7f86 100644
--- a/chrome/browser/safe_browsing/delayed_warning_navigation_throttle.cc
+++ b/chrome/browser/safe_browsing/delayed_warning_navigation_throttle.cc
@@ -53,8 +53,11 @@
   if (navigation_handle()->IsDownload() && observer) {
     // If the SafeBrowsing interstitial is delayed on the page, ignore
     // downloads. The observer will record the histogram entry for this.
-    navigation_handle()->GetWebContents()->GetMainFrame()->AddMessageToConsole(
-        blink::mojom::ConsoleMessageLevel::kWarning, kConsoleMessage);
+    navigation_handle()
+        ->GetWebContents()
+        ->GetPrimaryMainFrame()
+        ->AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kWarning,
+                              kConsoleMessage);
     return content::NavigationThrottle::CANCEL_AND_IGNORE;
   }
   return content::NavigationThrottle::PROCEED;
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
index 2e561dc..0bbc46f 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -620,7 +620,7 @@
         ->TestDidReceiveMouseDownEvent();
     std::unique_ptr<content::NavigationSimulator> navigation =
         content::NavigationSimulator::CreateRendererInitiated(
-            url, web_contents()->GetMainFrame());
+            url, web_contents()->GetPrimaryMainFrame());
 
     navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
     navigation->Commit();
@@ -2707,7 +2707,7 @@
   std::vector<base::FilePath::StringType> alternate_extensions{
       FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")};
   download_service_->CheckPPAPIDownloadRequest(
-      GURL("http://example.com/foo"), web_contents->GetMainFrame(),
+      GURL("http://example.com/foo"), web_contents->GetPrimaryMainFrame(),
       default_file_path, alternate_extensions, profile(),
       base::BindOnce(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
                      base::Unretained(this)));
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 2b2b8d37..13710c8 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -171,7 +171,9 @@
 }
 
 content::RenderFrameHost* GetRenderFrameHost(Browser* browser) {
-  return browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  return browser->tab_strip_model()
+      ->GetActiveWebContents()
+      ->GetPrimaryMainFrame();
 }
 
 class ClickEvent : public ui::Event {
@@ -193,7 +195,7 @@
 
 bool WaitForReady(Browser* browser) {
   WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
-  if (!content::WaitForRenderFrameReady(contents->GetMainFrame())) {
+  if (!content::WaitForRenderFrameReady(contents->GetPrimaryMainFrame())) {
     return false;
   }
   return IsShowingInterstitial(contents);
@@ -580,7 +582,7 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     security_interstitials::SecurityInterstitialPage* ssl_blocking_page;
 
-    EXPECT_TRUE(WaitForRenderFrameReady(contents->GetMainFrame()));
+    EXPECT_TRUE(WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
     security_interstitials::SecurityInterstitialTabHelper* helper =
         security_interstitials::SecurityInterstitialTabHelper::FromWebContents(
             contents);
@@ -1771,7 +1773,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   base::RunLoop().RunUntilIdle();
   WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(content::WaitForRenderFrameReady(contents->GetMainFrame()));
+  EXPECT_TRUE(
+      content::WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
   EXPECT_FALSE(IsShowingInterstitial(contents));
 }
 
@@ -1794,7 +1797,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   base::RunLoop().RunUntilIdle();
   WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(content::WaitForRenderFrameReady(contents->GetMainFrame()));
+  EXPECT_TRUE(
+      content::WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
   EXPECT_FALSE(IsShowingInterstitial(contents));
 }
 
@@ -1936,7 +1940,7 @@
         blink::WebInputEvent::GetStaticTimeStampForTests());
     event.text[0] = 'a';
     content::RenderWidgetHost* rwh =
-        contents->GetMainFrame()->GetRenderViewHost()->GetWidget();
+        contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
     rwh->ForwardKeyboardEvent(event);
     observer.WaitForNavigationFinished();
     return WaitForReady(browser);
@@ -1953,7 +1957,7 @@
     content::WebContents* contents =
         browser->tab_strip_model()->GetActiveWebContents();
     content::RenderWidgetHost* rwh =
-        contents->GetMainFrame()->GetRenderViewHost()->GetWidget();
+        contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
     rwh->ForwardMouseEvent(event);
   }
 
@@ -2231,7 +2235,7 @@
   // Browser expects a non-synthesized event to have an os_event. Make the
   // browser ignore this event instead.
   event.skip_in_browser = true;
-  contents->GetMainFrame()
+  contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardKeyboardEvent(event);
@@ -2263,7 +2267,7 @@
   // Browser expects a non-synthesized event to have an os_event. Make the
   // browser ignore this event instead.
   event.skip_in_browser = true;
-  contents->GetMainFrame()
+  contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardKeyboardEvent(event);
@@ -2294,7 +2298,7 @@
   event.native_key_code = ui::VKEY_C;
   // We don't set event.skip_in_browser = true here because the event will be
   // consumed by UserInteractionObserver and not passed to the browser.
-  contents->GetMainFrame()
+  contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardKeyboardEvent(event);
@@ -2329,7 +2333,7 @@
   // Browser expects a non-synthesized event to have an os_event. Make the
   // browser ignore this event instead.
   event.skip_in_browser = true;
-  contents->GetMainFrame()
+  contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardKeyboardEvent(event);
@@ -2580,7 +2584,7 @@
     SafeBrowsingService* sb_service =
         g_browser_process->safe_browsing_service();
     const content::GlobalRenderFrameHostId primary_main_frame_id =
-        contents->GetMainFrame()->GetGlobalId();
+        contents->GetPrimaryMainFrame()->GetGlobalId();
     SafeBrowsingBlockingPage::UnsafeResource resource;
 
     resource.url = request_url;
@@ -3200,7 +3204,7 @@
     content::WebContents* contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     content::TestFrameNavigationObserver error_page_navigation_observer(
-        contents->GetMainFrame());
+        contents->GetPrimaryMainFrame());
     // The error checking that the FencedFrameTestHelper performs is not
     // suitable for this case. The resulting error page is an interstitial shown
     // in the frame that owns the fenced frame, not in the fenced frame itself.
@@ -3213,7 +3217,7 @@
           document.body.appendChild(fencedFrame);
         })";
     EXPECT_TRUE(
-        content::ExecJs(contents->GetMainFrame(),
+        content::ExecJs(contents->GetPrimaryMainFrame(),
                         content::JsReplace(kAddFencedFrameScript, url)));
     error_page_navigation_observer.Wait();
     EXPECT_FALSE(error_page_navigation_observer.last_navigation_succeeded());
@@ -3248,7 +3252,7 @@
   ASSERT_FALSE(browser()
                    ->tab_strip_model()
                    ->GetActiveWebContents()
-                   ->GetMainFrame()
+                   ->GetPrimaryMainFrame()
                    ->IsErrorDocument());
   AddFencedFrameAndExpectInterstitial(fenced_frame_url);
 }
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
index be5b43c7..c156d3d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -264,7 +264,7 @@
     {
       std::string script = base::StringPrintf("clickLink('%s');", element_id);
       content::RenderFrameHost* script_executing_frame =
-          current_web_contents->GetMainFrame();
+          current_web_contents->GetPrimaryMainFrame();
       if (subframe_index != -1) {
         script_executing_frame =
             ChildFrameAt(script_executing_frame, subframe_index);
@@ -305,7 +305,7 @@
     {
       std::string script = base::StringPrintf("clickLink('%s');", element_id);
       content::RenderFrameHost* script_executing_frame =
-          current_web_contents->GetMainFrame();
+          current_web_contents->GetPrimaryMainFrame();
       if (subframe_index != -1) {
         script_executing_frame =
             ChildFrameAt(script_executing_frame, subframe_index);
@@ -441,7 +441,7 @@
                                            ReferrerChain* referrer_chain) {
     observer_manager_->IdentifyReferrerChainByRenderFrameHost(
         // We will assume the primary main frame here.
-        web_contents->GetMainFrame(),
+        web_contents->GetPrimaryMainFrame(),
         2,  // kDownloadAttributionUserGestureLimit
         referrer_chain);
   }
@@ -468,7 +468,7 @@
     observer_manager_->OnUserGestureConsumed(web_contents);
     EXPECT_LE(observer_manager_->IdentifyReferrerChainByHostingPage(
                   initiating_frame_url, web_contents->GetLastCommittedURL(),
-                  web_contents->GetMainFrame()->GetGlobalId(), tab_id,
+                  web_contents->GetPrimaryMainFrame()->GetGlobalId(), tab_id,
                   has_user_gesture,
                   2,  // kDownloadAttributionUserGestureLimit
                   referrer_chain),
@@ -2564,14 +2564,14 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
 
   auto initiator_outermost_main_frame_id =
-      web_contents()->GetMainFrame()->GetGlobalId();
+      web_contents()->GetPrimaryMainFrame()->GetGlobalId();
 
   auto* initial_web_contents = web_contents();
 
   ui_test_utils::UrlLoadObserver url_observer(
       new_window_url, content::NotificationService::AllSources());
   ASSERT_TRUE(
-      ExecJs(web_contents()->GetMainFrame(),
+      ExecJs(web_contents()->GetPrimaryMainFrame(),
              content::JsReplace("var w = window.open($1, 'New Window');",
                                 new_window_url)));
   url_observer.Wait();
@@ -2580,13 +2580,14 @@
   content::TestNavigationObserver navigation_observer(
       web_contents(), kExpectedNumberOfNavigations);
   ASSERT_TRUE(
-      ExecJs(initial_web_contents->GetMainFrame(),
+      ExecJs(initial_web_contents->GetPrimaryMainFrame(),
              content::JsReplace("w.document.querySelector('IFRAME').src = $1;",
                                 new_window_subframe_url)));
   navigation_observer.Wait();
   EXPECT_EQ(new_window_subframe_url, navigation_observer.last_navigation_url());
 
-  auto target_main_frame_id = web_contents()->GetMainFrame()->GetGlobalId();
+  auto target_main_frame_id =
+      web_contents()->GetPrimaryMainFrame()->GetGlobalId();
 
   ReferrerChain referrer_chain;
   IdentifyReferrerChainByEventURL(
@@ -2661,13 +2662,13 @@
                                    content::GlobalRenderFrameHostId());
   ASSERT_TRUE(index);
   nav_event = GetNavigationEvent(*index);
-  EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(),
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
             nav_event->outermost_main_frame_id);
 
   // If the initial main frame runs JS to initiate this subframe navigation, the
   // the navigation request's initiator frame is in the current frame tree,
   // not the frame in which the JS ran.
-  EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(),
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
             nav_event->initiator_outermost_main_frame_id);
 }
 
@@ -2688,7 +2689,7 @@
   ReferrerChain referrer_chain;
   IdentifyReferrerChainByEventURL(
       next_url, sessions::SessionTabHelper::IdForTab(web_contents()),
-      web_contents()->GetMainFrame()->GetGlobalId(), &referrer_chain);
+      web_contents()->GetPrimaryMainFrame()->GetGlobalId(), &referrer_chain);
 
   EXPECT_EQ(2, referrer_chain.size());
 
@@ -2741,7 +2742,7 @@
   // Since we're supplying the id for the primary page's outermost main frame,
   // we should find the event for the primary page.
   auto index_b = FindNavigationEventIndex(
-      prerendered_url, web_contents()->GetMainFrame()->GetGlobalId());
+      prerendered_url, web_contents()->GetPrimaryMainFrame()->GetGlobalId());
 
   // Ensure that these indices are valid and not equal.
   EXPECT_TRUE(index_a && index_b);
@@ -2798,7 +2799,7 @@
   referrer_chain.Clear();
   IdentifyReferrerChainByEventURL(
       prerendered_url, sessions::SessionTabHelper::IdForTab(web_contents()),
-      web_contents()->GetMainFrame()->GetGlobalId(), &referrer_chain);
+      web_contents()->GetPrimaryMainFrame()->GetGlobalId(), &referrer_chain);
 
   EXPECT_EQ(2, referrer_chain.size());
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 0482b1b..885490d8 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -776,7 +776,7 @@
   // malware image, and also starts a renderer-initiated top-level navigation to
   // a site that does not respond.  Should show interstitial and have first page
   // in referrer.
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"navigateAndLoadMalwareImage()", base::NullCallback());
   load_stop_observer.Wait();
 
@@ -818,7 +818,7 @@
       .Times(1);
 
   WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* rfh = contents->GetMainFrame();
+  content::RenderFrameHost* rfh = contents->GetPrimaryMainFrame();
   content::LoadStopObserver load_stop_observer(contents);
   // Start a browser initiated top-level navigation to a site that does not
   // respond.
@@ -855,13 +855,14 @@
   // Have the current tab open a new tab with window.open().
   WebContents* main_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* main_rfh = main_contents->GetMainFrame();
+  content::RenderFrameHost* main_rfh = main_contents->GetPrimaryMainFrame();
 
   content::WebContentsAddedObserver web_contents_added_observer;
   main_rfh->ExecuteJavaScriptForTests(u"w=window.open();",
                                       base::NullCallback());
   WebContents* new_tab_contents = web_contents_added_observer.GetWebContents();
-  content::RenderFrameHost* new_tab_rfh = new_tab_contents->GetMainFrame();
+  content::RenderFrameHost* new_tab_rfh =
+      new_tab_contents->GetPrimaryMainFrame();
   // A fresh WebContents should be on the initial NavigationEntry, or have
   // no NavigationEntry (if InitialNavigationEntry is disabled).
   EXPECT_TRUE(!new_tab_contents->GetController().GetLastCommittedEntry() ||
diff --git a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc
index 6e774ec..5013b17b 100644
--- a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc
+++ b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc
@@ -160,9 +160,9 @@
     service_->AddObserver(this);
   }
 
-  if (web_contents && web_contents->GetMainFrame() &&
-      web_contents->GetMainFrame()->GetView()) {
-    focused = web_contents->GetMainFrame()->GetView()->HasFocus();
+  if (web_contents && web_contents->GetPrimaryMainFrame() &&
+      web_contents->GetPrimaryMainFrame()->GetView()) {
+    focused = web_contents->GetPrimaryMainFrame()->GetView()->HasFocus();
   }
   UpdateFocusAndURL(focused, web_contents->GetLastCommittedURL());
 }
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
index e3c6271..6cb40b4 100644
--- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
+++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -231,7 +231,7 @@
   content::RenderFrameHost* rfh =
       content::DownloadItemUtils::GetRenderFrameHost(item);
   if (!rfh && web_contents)
-    rfh = web_contents->GetMainFrame();
+    rfh = web_contents->GetPrimaryMainFrame();
 
   FillReferrerChain(web_contents, rfh, report.get());
 
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc
index 6763544..7b1e689 100644
--- a/chrome/browser/safe_browsing/threat_details_unittest.cc
+++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -274,7 +274,7 @@
                     const GURL& url,
                     UnsafeResource* resource) {
     const content::GlobalRenderFrameHostId primary_main_frame_id =
-        web_contents()->GetMainFrame()->GetGlobalId();
+        web_contents()->GetPrimaryMainFrame()->GetGlobalId();
     resource->url = url;
     resource->is_subresource = is_subresource;
     resource->threat_type = threat_type;
@@ -500,7 +500,7 @@
   returned_referrer_chain.Add()->set_url(kSecondRedirectURL);
   EXPECT_CALL(*referrer_chain_provider_,
               IdentifyReferrerChainByRenderFrameHost(
-                  web_contents()->GetMainFrame(), _, _))
+                  web_contents()->GetPrimaryMainFrame(), _, _))
       .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain),
                       Return(ReferrerChainProvider::SUCCESS)));
 
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc
index 29ffa579..00a03a3 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.cc
+++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -91,7 +91,7 @@
   // indicate that it wants the key press to be ignored.
   // (DidGetUserInteraction() can only observe and not cancel the event.)
   content::RenderWidgetHost* widget =
-      web_contents->GetMainFrame()->GetRenderWidgetHost();
+      web_contents->GetPrimaryMainFrame()->GetRenderWidgetHost();
   widget->AddKeyPressEventCallback(key_press_callback_);
   widget->AddMouseEventCallback(mouse_event_callback_);
 
@@ -110,11 +110,11 @@
     permission_request_manager->RemoveObserver(this);
   }
   web_contents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->GetRenderWidgetHost()
       ->RemoveKeyPressEventCallback(key_press_callback_);
   web_contents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->GetRenderWidgetHost()
       ->RemoveMouseEventCallback(mouse_event_callback_);
 }
@@ -142,7 +142,7 @@
     content::RenderFrameHost* new_frame) {
   // We currently only insert callbacks on the widget for the top-level main
   // frame.
-  if (new_frame != web_contents()->GetMainFrame())
+  if (new_frame != web_contents()->GetPrimaryMainFrame())
     return;
   // The `old_frame` is null when the `new_frame` is the initial
   // RenderFrameHost, which we already attached to in the constructor.
@@ -358,7 +358,7 @@
 
 void SafeBrowsingUserInteractionObserver::CleanUp() {
   content::RenderWidgetHost* widget =
-      web_contents()->GetMainFrame()->GetRenderWidgetHost();
+      web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost();
   widget->RemoveKeyPressEventCallback(key_press_callback_);
   widget->RemoveMouseEventCallback(mouse_event_callback_);
 }
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index 26fc116e..556d108 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -216,7 +216,7 @@
   return false;
 #else
   content::RenderProcessHost* process_host =
-      contents->GetMainFrame()->GetProcess();
+      contents->GetPrimaryMainFrame()->GetProcess();
   if (!process_host)
     return false;
 
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index fc53a45..a20a904 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -97,7 +97,7 @@
     InstantService* instant_service =
         InstantServiceFactory::GetForProfile(profile());
     return instant_service->IsInstantProcess(
-        contents->GetMainFrame()->GetProcess()->GetID());
+        contents->GetPrimaryMainFrame()->GetProcess()->GetID());
   }
 
   // Each test case represents a navigation to |start_url| followed by a
@@ -209,9 +209,9 @@
     const scoped_refptr<content::SiteInstance> start_site_instance =
         contents->GetSiteInstance();
     const content::RenderProcessHost* start_rph =
-        contents->GetMainFrame()->GetProcess();
+        contents->GetPrimaryMainFrame()->GetProcess();
     const content::RenderViewHost* start_rvh =
-        contents->GetMainFrame()->GetRenderViewHost();
+        contents->GetPrimaryMainFrame()->GetRenderViewHost();
 
     // Navigate to end URL.
     NavigateAndCommitActiveTab(GURL(test.end_url));
@@ -222,10 +222,10 @@
               start_site_instance.get() == contents->GetSiteInstance())
         << test.description;
     EXPECT_EQ(test.same_site_instance,
-              start_rvh == contents->GetMainFrame()->GetRenderViewHost())
+              start_rvh == contents->GetPrimaryMainFrame()->GetRenderViewHost())
         << test.description;
     EXPECT_EQ(test.same_process,
-              start_rph == contents->GetMainFrame()->GetProcess())
+              start_rph == contents->GetPrimaryMainFrame()->GetProcess())
         << test.description;
   }
 }
@@ -246,13 +246,13 @@
     const scoped_refptr<content::SiteInstance> start_site_instance =
         contents->GetSiteInstance();
     const content::RenderProcessHost* start_rph =
-        contents->GetMainFrame()->GetProcess();
+        contents->GetPrimaryMainFrame()->GetProcess();
     const content::RenderViewHost* start_rvh =
-        contents->GetMainFrame()->GetRenderViewHost();
+        contents->GetPrimaryMainFrame()->GetRenderViewHost();
 
     // Navigate to end URL via a renderer-initiated navigation.
     content::NavigationSimulator::NavigateAndCommitFromDocument(
-        GURL(test.end_url), contents->GetMainFrame());
+        GURL(test.end_url), contents->GetPrimaryMainFrame());
 
     EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents))
         << test.description;
@@ -261,10 +261,10 @@
               start_site_instance.get() == contents->GetSiteInstance())
         << test.description;
     EXPECT_EQ(test.same_site_instance,
-              start_rvh == contents->GetMainFrame()->GetRenderViewHost())
+              start_rvh == contents->GetPrimaryMainFrame()->GetRenderViewHost())
         << test.description;
     EXPECT_EQ(test.same_process,
-              start_rph == contents->GetMainFrame()->GetProcess())
+              start_rph == contents->GetPrimaryMainFrame()->GetProcess())
         << test.description;
   }
 }
diff --git a/chrome/browser/segmentation_platform/default_model/feed_user_segment.cc b/chrome/browser/segmentation_platform/default_model/feed_user_segment.cc
index c90324d9..8cc0bb8 100644
--- a/chrome/browser/segmentation_platform/default_model/feed_user_segment.cc
+++ b/chrome/browser/segmentation_platform/default_model/feed_user_segment.cc
@@ -30,28 +30,42 @@
 
 // Discrete mapping parameters.
 constexpr char kFeedUserDiscreteMappingKey[] = "feed_user_segment";
-constexpr float kFeedUserDiscreteMappingMinResult = 1;
+constexpr float kFeedUserDiscreteMappingMinResult = 0.8;
 constexpr int64_t kFeedUserDiscreteMappingRank = 1;
 constexpr std::pair<float, int> kDiscreteMappings[] = {
     {kFeedUserDiscreteMappingMinResult, kFeedUserDiscreteMappingRank}};
 
-static constexpr std::array<std::pair<float, /*FeedUserSubsegment*/ int>, 8>
+#define RANK(x) static_cast<int>(FeedUserSubsegment::x)
+
+static constexpr std::array<std::pair<float, /*FeedUserSubsegment*/ int>, 16>
     kFeedUserScoreToSubGroup = {{
-        {1.0, static_cast<int>(FeedUserSubsegment::kActiveOnFeedOnly)},
-        {0.8,
-         static_cast<int>(FeedUserSubsegment::kActiveOnFeedAndNtpFeatures)},
-        {0.7, static_cast<int>(FeedUserSubsegment::kNoFeedAndNtpFeatures)},
-        {0.5, static_cast<int>(FeedUserSubsegment::kMvtOnly)},
-        {0.4, static_cast<int>(FeedUserSubsegment::kReturnToCurrentTabOnly)},
-        {0.2, static_cast<int>(FeedUserSubsegment::kUsedNtpWithoutModules)},
-        {0.1, static_cast<int>(FeedUserSubsegment::kNoNTPOrHomeOpened)},
-        {0.0, static_cast<int>(FeedUserSubsegment::kUnknown)},
+        {1.0, RANK(kDeprecatedActiveOnFeedOnly)},
+        {0.98, RANK(kNtpAndFeedEngaged)},
+        {0.96, RANK(kNtpAndFeedEngagedSimple)},
+        {0.94, RANK(kNtpAndFeedScrolled)},
+        {0.92, RANK(kNtpAndFeedInteracted)},
+        {0.90, RANK(kNoNtpAndFeedEngaged)},
+        {0.88, RANK(kNoNtpAndFeedEngagedSimple)},
+        {0.86, RANK(kNoNtpAndFeedScrolled)},
+        {0.84, RANK(kNoNtpAndFeedInteracted)},
+        {0.8, RANK(kDeprecatedActiveOnFeedAndNtpFeatures)},
+        {0.7, RANK(kNoFeedAndNtpFeatures)},
+        {0.5, RANK(kMvtOnly)},
+        {0.4, RANK(kReturnToCurrentTabOnly)},
+        {0.2, RANK(kUsedNtpWithoutModules)},
+        {0.1, RANK(kNoNTPOrHomeOpened)},
+        {0.0, RANK(kUnknown)},
     }};
 
 // InputFeatures.
-// Any updates to these strings need to also update the field trials allowlist
-// in go/segmentation-field-trials-map.
-constexpr std::array<MetadataWriter::UMAFeature, 9> kFeedUserUMAFeatures = {
+
+// The enum values are based on feed::FeedEngagementType.
+constexpr std::array<int32_t, 1> kFeedEngagementEngaged{0};
+constexpr std::array<int32_t, 1> kFeedEngagementSimple{1};
+constexpr std::array<int32_t, 1> kFeedEngagementInteracted{2};
+constexpr std::array<int32_t, 1> kFeedEngagementScrolled{4};
+
+constexpr std::array<MetadataWriter::UMAFeature, 13> kFeedUserUMAFeatures = {
     MetadataWriter::UMAFeature::FromUserAction(
         "ContentSuggestions.Feed.CardAction.Open",
         14),
@@ -67,7 +81,28 @@
     MetadataWriter::UMAFeature::FromUserAction("MobileMenuRecentTabs", 14),
     MetadataWriter::UMAFeature::FromUserAction("MobileMenuHistory", 14),
     MetadataWriter::UMAFeature::FromUserAction("MobileTabReturnedToCurrentTab",
-                                               14)};
+                                               14),
+    MetadataWriter::UMAFeature::FromEnumHistogram(
+        "ContentSuggestions.Feed.EngagementType",
+        14,
+        kFeedEngagementEngaged.data(),
+        kFeedEngagementEngaged.size()),
+    MetadataWriter::UMAFeature::FromEnumHistogram(
+        "ContentSuggestions.Feed.EngagementType",
+        14,
+        kFeedEngagementSimple.data(),
+        kFeedEngagementSimple.size()),
+    MetadataWriter::UMAFeature::FromEnumHistogram(
+        "ContentSuggestions.Feed.EngagementType",
+        14,
+        kFeedEngagementInteracted.data(),
+        kFeedEngagementInteracted.size()),
+    MetadataWriter::UMAFeature::FromEnumHistogram(
+        "ContentSuggestions.Feed.EngagementType",
+        14,
+        kFeedEngagementScrolled.data(),
+        kFeedEngagementScrolled.size()),
+};
 
 float GetScoreForSubsegment(FeedUserSubsegment subgroup) {
   for (const auto& score_and_type : kFeedUserScoreToSubGroup) {
@@ -79,15 +114,17 @@
   return 0;
 }
 
+// Any updates to these strings need to also update the field trials allowlist
+// in go/segmentation-field-trials-map.
 std::string FeedUserSubsegmentToString(FeedUserSubsegment feed_group) {
   switch (feed_group) {
     case FeedUserSubsegment::kUnknown:
       return "Unknown";
     case FeedUserSubsegment::kOther:
       return "Other";
-    case FeedUserSubsegment::kActiveOnFeedOnly:
+    case FeedUserSubsegment::kDeprecatedActiveOnFeedOnly:
       return "ActiveOnFeedOnly";
-    case FeedUserSubsegment::kActiveOnFeedAndNtpFeatures:
+    case FeedUserSubsegment::kDeprecatedActiveOnFeedAndNtpFeatures:
       return "ActiveOnFeedAndNtpFeatures";
     case FeedUserSubsegment::kNoFeedAndNtpFeatures:
       return "NoFeedAndNtpFeatures";
@@ -99,6 +136,22 @@
       return "UsedNtpWithoutModules";
     case FeedUserSubsegment::kNoNTPOrHomeOpened:
       return "NoNTPOrHomeOpened";
+    case FeedUserSubsegment::kNtpAndFeedEngaged:
+      return "NtpAndFeedEngaged";
+    case FeedUserSubsegment::kNtpAndFeedEngagedSimple:
+      return "NtpAndFeedEngagedSimple";
+    case FeedUserSubsegment::kNtpAndFeedScrolled:
+      return "NtpAndFeedScrolled";
+    case FeedUserSubsegment::kNtpAndFeedInteracted:
+      return "NtpAndFeedInteracted";
+    case FeedUserSubsegment::kNoNtpAndFeedEngaged:
+      return "NoNtpAndFeedEngaged";
+    case FeedUserSubsegment::kNoNtpAndFeedEngagedSimple:
+      return "NoNtpAndFeedEngagedSimple";
+    case FeedUserSubsegment::kNoNtpAndFeedScrolled:
+      return "NoNtpAndFeedScrolled";
+    case FeedUserSubsegment::kNoNtpAndFeedInteracted:
+      return "NoNtpAndFeedInteracted";
   }
 }
 
@@ -108,8 +161,8 @@
 
 absl::optional<std::string> FeedUserSegment::GetSubsegmentName(
     int subsegment_rank) {
-  DCHECK(static_cast<int>(FeedUserSubsegment::kUnknown) <= subsegment_rank &&
-         subsegment_rank <= static_cast<int>(FeedUserSubsegment::kMaxValue));
+  DCHECK(RANK(kUnknown) <= subsegment_rank &&
+         subsegment_rank <= RANK(kMaxValue));
   FeedUserSubsegment subgroup =
       static_cast<FeedUserSubsegment>(subsegment_rank);
   return FeedUserSubsegmentToString(subgroup);
@@ -155,18 +208,29 @@
 
   FeedUserSubsegment segment = FeedUserSubsegment::kNoNTPOrHomeOpened;
 
-  const bool feed_opened = (inputs[0] + inputs[1] + inputs[2]) >= 2;
+  const bool feed_engaged = inputs[9] >= 2;
+  const bool feed_engaged_simple = inputs[10] >= 2;
+  const bool feed_interacted = inputs[11] >= 2;
+  const bool feed_scrolled = inputs[12] >= 2;
+
   const bool mv_tiles_used = inputs[3] >= 2;
   const bool return_to_tab_used = inputs[8] >= 2;
-  const bool home_or_ntp_used = (inputs[4] + inputs[5]) >= 4;
+  const bool ntp_used = mv_tiles_used || return_to_tab_used;
+  const bool home_or_ntp_opened = (inputs[4] + inputs[5]) >= 4;
 
-  if (feed_opened) {
-    if (mv_tiles_used || return_to_tab_used) {
-      segment = FeedUserSubsegment::kActiveOnFeedAndNtpFeatures;
-    } else {
-      segment = FeedUserSubsegment::kActiveOnFeedOnly;
-    }
-  } else if (home_or_ntp_used) {
+  if (feed_engaged) {
+    segment = ntp_used ? FeedUserSubsegment::kNtpAndFeedEngaged
+                       : FeedUserSubsegment::kNoNtpAndFeedEngaged;
+  } else if (feed_engaged_simple) {
+    segment = ntp_used ? FeedUserSubsegment::kNtpAndFeedEngagedSimple
+                       : FeedUserSubsegment::kNoNtpAndFeedEngagedSimple;
+  } else if (feed_interacted) {
+    segment = ntp_used ? FeedUserSubsegment::kNtpAndFeedInteracted
+                       : FeedUserSubsegment::kNoNtpAndFeedInteracted;
+  } else if (feed_scrolled) {
+    segment = ntp_used ? FeedUserSubsegment::kNtpAndFeedScrolled
+                       : FeedUserSubsegment::kNoNtpAndFeedScrolled;
+  } else if (home_or_ntp_opened) {
     if (mv_tiles_used && return_to_tab_used) {
       segment = FeedUserSubsegment::kNoFeedAndNtpFeatures;
     } else if (mv_tiles_used) {
diff --git a/chrome/browser/segmentation_platform/default_model/feed_user_segment.h b/chrome/browser/segmentation_platform/default_model/feed_user_segment.h
index 5ca701e5..0583ed6 100644
--- a/chrome/browser/segmentation_platform/default_model/feed_user_segment.h
+++ b/chrome/browser/segmentation_platform/default_model/feed_user_segment.h
@@ -13,14 +13,28 @@
 enum class FeedUserSubsegment {
   kUnknown = 0,
   kOther = 1,
-  kActiveOnFeedOnly = 2,
-  kActiveOnFeedAndNtpFeatures = 3,
+
+  // Legacy groups, split into feed engagement types below.
+  kDeprecatedActiveOnFeedOnly = 2,
+  kDeprecatedActiveOnFeedAndNtpFeatures = 3,
+
+  // Recorded when no feed usage was observed.
   kNoFeedAndNtpFeatures = 4,
   kMvtOnly = 5,
   kReturnToCurrentTabOnly = 6,
   kUsedNtpWithoutModules = 7,
   kNoNTPOrHomeOpened = 8,
-  kMaxValue = kNoNTPOrHomeOpened
+
+  // Feed engagement combined with NTP features.
+  kNtpAndFeedEngaged = 9,
+  kNtpAndFeedEngagedSimple = 10,
+  kNtpAndFeedScrolled = 11,
+  kNtpAndFeedInteracted = 12,
+  kNoNtpAndFeedEngaged = 13,
+  kNoNtpAndFeedEngagedSimple = 14,
+  kNoNtpAndFeedScrolled = 15,
+  kNoNtpAndFeedInteracted = 16,
+  kMaxValue = kNoNtpAndFeedInteracted
 };
 
 // Segmentation Chrome Feed user model provider. Provides a default model and
diff --git a/chrome/browser/segmentation_platform/default_model/feed_user_segment_unittest.cc b/chrome/browser/segmentation_platform/default_model/feed_user_segment_unittest.cc
index af2f21a8..439de001 100644
--- a/chrome/browser/segmentation_platform/default_model/feed_user_segment_unittest.cc
+++ b/chrome/browser/segmentation_platform/default_model/feed_user_segment_unittest.cc
@@ -78,7 +78,7 @@
   ExpectInitAndFetchModel();
   ASSERT_TRUE(fetched_metadata_);
 
-  std::vector<float> input(9, 0);
+  std::vector<float> input(13, 0);
 
   absl::optional<float> result = ExpectExecutionWithInput(input);
   ASSERT_TRUE(result);
@@ -104,12 +104,11 @@
       FeedUserSegment::GetSubsegmentName(metadata_utils::ConvertToDiscreteScore(
           "feed_user_segment_subsegment", *result, *fetched_metadata_)));
 
-  input[0] = 1;
-  input[2] = 2;
+  input[10] = 3;
   result = ExpectExecutionWithInput(input);
   ASSERT_TRUE(result);
   EXPECT_EQ(
-      "ActiveOnFeedAndNtpFeatures",
+      "NtpAndFeedEngagedSimple",
       FeedUserSegment::GetSubsegmentName(metadata_utils::ConvertToDiscreteScore(
           "feed_user_segment_subsegment", *result, *fetched_metadata_)));
 
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
index 23aeadd..31c48e39 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
@@ -116,7 +116,7 @@
 
   std::unique_ptr<content::NavigationSimulator> simulator =
       content::NavigationSimulator::CreateRendererInitiated(
-          GURL(kHttpsUrl2), web_contents()->GetMainFrame());
+          GURL(kHttpsUrl2), web_contents()->GetPrimaryMainFrame());
   simulator->SetTransition(ui::PAGE_TRANSITION_LINK);
   simulator->Start();
   ASSERT_TRUE(web_contents()->IsWaitingForResponse());
diff --git a/chrome/browser/serial/chrome_serial_browsertest.cc b/chrome/browser/serial/chrome_serial_browsertest.cc
index 17099ed..9720c08 100644
--- a/chrome/browser/serial/chrome_serial_browsertest.cc
+++ b/chrome/browser/serial/chrome_serial_browsertest.cc
@@ -109,7 +109,8 @@
   // Create port and grant permission to it.
   auto port = device::mojom::SerialPortInfo::New();
   port->token = base::UnguessableToken::Create();
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   context()->GrantPortPermission(origin, *port);
   port_manager().AddPort(port.Clone());
 
@@ -140,7 +141,8 @@
   // Create port and grant permission to it.
   auto port = device::mojom::SerialPortInfo::New();
   port->token = base::UnguessableToken::Create();
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   context()->GrantPortPermission(origin, *port);
   port_manager().AddPort(port.Clone());
 
@@ -166,7 +168,8 @@
   // Create port and grant permission to it.
   auto port = device::mojom::SerialPortInfo::New();
   port->token = base::UnguessableToken::Create();
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   context()->GrantPortPermission(origin, *port);
   port_manager().AddPort(port.Clone());
 
@@ -217,7 +220,8 @@
   port->vendor_id = 0x18D1;
   port->has_product_id = true;
   port->product_id = 0x58F0;
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   context()->GrantPortPermission(origin, *port);
   port_manager().AddPort(port.Clone());
 
diff --git a/chrome/browser/sessions/closed_tab_cache_browsertest.cc b/chrome/browser/sessions/closed_tab_cache_browsertest.cc
index 04bb19fa..1944ecd 100644
--- a/chrome/browser/sessions/closed_tab_cache_browsertest.cc
+++ b/chrome/browser/sessions/closed_tab_cache_browsertest.cc
@@ -141,7 +141,7 @@
   // Don't cache WebContents when beforeunload listeners are run.
   NavigateToURL(browser(), "a.com");
   content::WebContents* a = browser()->tab_strip_model()->GetWebContentsAt(1);
-  EXPECT_TRUE(ExecJs(a->GetMainFrame(),
+  EXPECT_TRUE(ExecJs(a->GetPrimaryMainFrame(),
                      "window.addEventListener('beforeunload', function (e) "
                      "{e.returnValue = '';});"));
   EXPECT_TRUE(a->NeedToFireBeforeUnloadOrUnloadEvents());
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 9483f28..b4f3be7 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -1338,7 +1338,7 @@
   content::WebContents* old_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
-              old_tab->GetMainFrame()->GetEnabledBindings());
+              old_tab->GetPrimaryMainFrame()->GetEnabledBindings());
 
   Browser* new_browser = QuitBrowserAndRestore(browser());
   ASSERT_EQ(1u, active_browser_list_->size());
@@ -1346,7 +1346,7 @@
       new_browser->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(webui_url, new_tab->GetURL());
   EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
-              new_tab->GetMainFrame()->GetEnabledBindings());
+              new_tab->GetPrimaryMainFrame()->GetEnabledBindings());
 }
 
 // http://crbug.com/803510 : Flaky on dbg and ASan bots.
@@ -1360,7 +1360,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), webui_url));
   content::WebContents* old_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(old_tab->GetMainFrame()->GetEnabledBindings() &
+  EXPECT_TRUE(old_tab->GetPrimaryMainFrame()->GetEnabledBindings() &
               content::BINDINGS_POLICY_WEB_UI);
 
   Browser* new_browser = QuitBrowserAndRestore(browser());
@@ -1368,7 +1368,7 @@
   content::WebContents* new_tab =
       new_browser->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(webui_url, new_tab->GetURL());
-  EXPECT_TRUE(new_tab->GetMainFrame()->GetEnabledBindings() &
+  EXPECT_TRUE(new_tab->GetPrimaryMainFrame()->GetEnabledBindings() &
               content::BINDINGS_POLICY_WEB_UI);
 }
 
@@ -2508,7 +2508,7 @@
     ASSERT_TRUE(ExecJs(tab1, "var w = window.open('/title2.html');"));
     old_popup = popup_observer.GetWebContents();
     EXPECT_EQ(initial_origin,
-              old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
     EXPECT_TRUE(WaitForLoadStop(old_popup));
   }
 
@@ -2520,9 +2520,9 @@
     ASSERT_TRUE(ExecJs(tab1, "w.location.href = 'about:blank';"));
     nav_observer.Wait();
     EXPECT_EQ(GURL(url::kAboutBlankURL),
-              old_popup->GetMainFrame()->GetLastCommittedURL());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
     EXPECT_EQ(initial_origin,
-              old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
 
   // Navigate the popup to another site.
@@ -2534,8 +2534,9 @@
         old_popup, content::JsReplace("location = $1", other_url)));
     nav_observer.Wait();
   }
-  EXPECT_EQ(other_url, old_popup->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, old_popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(old_popup->GetController().CanGoBack());
 
   // Kill the original browser then open a new one to trigger a restore.
@@ -2546,8 +2547,9 @@
   old_popup = nullptr;
 
   // Verify that the restored popup hosts |other_url|.
-  EXPECT_EQ(other_url, new_popup->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, new_popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(new_popup->GetController().CanGoBack());
 
   // Navigate the popup back to about:blank.
@@ -2557,9 +2559,9 @@
     nav_observer.Wait();
   }
   EXPECT_EQ(GURL(url::kAboutBlankURL),
-            new_popup->GetMainFrame()->GetLastCommittedURL());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_origin,
-            new_popup->GetMainFrame()->GetLastCommittedOrigin());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 // Test that it is possible to navigate back to a restored about:blank history
@@ -2574,8 +2576,9 @@
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
   content::WebContents* old_tab = GetTab(browser(), 0);
   EXPECT_EQ(GURL(url::kAboutBlankURL),
-            old_tab->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_TRUE(old_tab->GetMainFrame()->GetLastCommittedOrigin().opaque());
+            old_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_TRUE(
+      old_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
 
   // Navigate the tab to another site.
   GURL other_url = embedded_test_server()->GetURL("bar.com", "/title1.html");
@@ -2586,8 +2589,9 @@
         old_tab, content::JsReplace("location = $1", other_url)));
     nav_observer.Wait();
   }
-  EXPECT_EQ(other_url, old_tab->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, old_tab->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, old_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            old_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(old_tab->GetController().CanGoBack());
 
   // Kill the original browser then open a new one to trigger a restore.
@@ -2598,8 +2602,9 @@
   old_tab = nullptr;
 
   // Verify that the restored popup hosts |other_url|.
-  EXPECT_EQ(other_url, new_tab->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, new_tab->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, new_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            new_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(new_tab->GetController().CanGoBack());
 
   // Navigate the popup back to about:blank.
@@ -2609,8 +2614,9 @@
     nav_observer.Wait();
   }
   EXPECT_EQ(GURL(url::kAboutBlankURL),
-            new_tab->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_TRUE(new_tab->GetMainFrame()->GetLastCommittedOrigin().opaque());
+            new_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_TRUE(
+      new_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
 }
 
 // Test that it is possible to navigate back to a restored about:blank history
@@ -2631,9 +2637,9 @@
     ASSERT_TRUE(ExecJs(tab1, "window.open('about:blank#foo')"));
     content::WebContents* old_popup = popup_observer.GetWebContents();
     EXPECT_EQ(GURL("about:blank#foo"),
-              old_popup->GetMainFrame()->GetLastCommittedURL());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
     EXPECT_EQ(initial_origin,
-              old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
 
   // Kill the original browser then open a new one to trigger a restore.
@@ -2644,9 +2650,9 @@
 
   // Verify that the restored popup hosts about:blank#foo.
   EXPECT_EQ(GURL("about:blank#foo"),
-            new_popup->GetMainFrame()->GetLastCommittedURL());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_origin,
-            new_popup->GetMainFrame()->GetLastCommittedOrigin());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   // Navigate the popup to another site.
   GURL other_url = embedded_test_server()->GetURL("bar.com", "/title1.html");
@@ -2657,8 +2663,9 @@
         new_popup, content::JsReplace("location = $1", other_url)));
     nav_observer.Wait();
   }
-  EXPECT_EQ(other_url, new_popup->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, new_popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(new_popup->GetController().CanGoBack());
 
   // Navigate the popup back to about:blank#foo.
@@ -2668,9 +2675,9 @@
     nav_observer.Wait();
   }
   EXPECT_EQ(GURL("about:blank#foo"),
-            new_popup->GetMainFrame()->GetLastCommittedURL());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_origin,
-            new_popup->GetMainFrame()->GetLastCommittedOrigin());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 // Test that it is possible to navigate back to a subframe with a restored
@@ -2686,7 +2693,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   content::WebContents* old_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHostWrapper old_tab_main_frame(old_tab->GetMainFrame());
+  content::RenderFrameHostWrapper old_tab_main_frame(
+      old_tab->GetPrimaryMainFrame());
   EXPECT_EQ(main_url, old_tab_main_frame->GetLastCommittedURL());
   EXPECT_EQ(a_origin, old_tab_main_frame->GetLastCommittedOrigin());
   content::RenderFrameHost* subframe =
@@ -2732,7 +2740,7 @@
   ASSERT_TRUE(new_tab->GetController().CanGoBack());
   old_tab = nullptr;
 
-  content::RenderFrameHost* new_tab_main_frame = new_tab->GetMainFrame();
+  content::RenderFrameHost* new_tab_main_frame = new_tab->GetPrimaryMainFrame();
   // Verify that the restored tab hosts: a.com(c.com).
   EXPECT_EQ(main_url, new_tab_main_frame->GetLastCommittedURL());
   EXPECT_EQ(a_origin, new_tab_main_frame->GetLastCommittedOrigin());
@@ -2782,8 +2790,9 @@
     ASSERT_TRUE(ExecJs(tab1, "window.open('/nocontent')"));
     old_popup = popup_observer.GetWebContents();
     EXPECT_EQ(GURL::EmptyGURL(),
-              old_popup->GetMainFrame()->GetLastCommittedURL());
-    EXPECT_EQ(main_origin, old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+    EXPECT_EQ(main_origin,
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
     EXPECT_TRUE(
         old_popup->GetController().GetLastCommittedEntry()->IsInitialEntry());
   }
@@ -2798,9 +2807,10 @@
 
   // Verify that the restored tab is the main tab instead of the initial
   // NavigationEntry tab.
-  EXPECT_EQ(main_url, new_browser_tab->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(main_url,
+            new_browser_tab->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(main_origin,
-            new_browser_tab->GetMainFrame()->GetLastCommittedOrigin());
+            new_browser_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   EXPECT_FALSE(new_browser_tab->GetController()
                    .GetLastCommittedEntry()
                    ->IsInitialEntry());
@@ -3025,8 +3035,8 @@
     loop.Run();
   }
   // The navigation has not completed, but the renderer has come alive.
-  EXPECT_TRUE(wc->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_EQ(wc->GetMainFrame()->GetLastCommittedURL().spec(), "");
+  EXPECT_TRUE(wc->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_EQ(wc->GetPrimaryMainFrame()->GetLastCommittedURL().spec(), "");
 
   // Now try to navigate to `url2`. We're currently trying to load `url1` since
   // the above navigation will be delayed. Going to `url2` should be a
@@ -3106,8 +3116,8 @@
     loop.Run();
   }
   // The navigation has not completed, but the renderer has come alive.
-  EXPECT_TRUE(wc->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_EQ(wc->GetMainFrame()->GetLastCommittedURL().spec(), "");
+  EXPECT_TRUE(wc->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_EQ(wc->GetPrimaryMainFrame()->GetLastCommittedURL().spec(), "");
 
   content::NavigationHandleCommitObserver back_observer(wc, url1);
   // Now try to go back. We're currently at `url2`, so going back to `url1`
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc
index 9f91d31..9b84c0a2 100644
--- a/chrome/browser/sessions/tab_restore_browsertest.cc
+++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -1769,7 +1769,7 @@
     old_popup = popup_observer.GetWebContents();
     EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
     EXPECT_EQ(initial_origin,
-              old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
     EXPECT_TRUE(WaitForLoadStop(old_popup));
   }
 
@@ -1781,9 +1781,9 @@
     ASSERT_TRUE(ExecJs(tab1, "w.location.href = 'about:blank';"));
     nav_observer.Wait();
     EXPECT_EQ(GURL(url::kAboutBlankURL),
-              old_popup->GetMainFrame()->GetLastCommittedURL());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
     EXPECT_EQ(initial_origin,
-              old_popup->GetMainFrame()->GetLastCommittedOrigin());
+              old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   }
 
   // Navigate the popup to another site.
@@ -1795,8 +1795,9 @@
         old_popup, content::JsReplace("location = $1", other_url)));
     nav_observer.Wait();
   }
-  EXPECT_EQ(other_url, old_popup->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, old_popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, old_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            old_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(old_popup->GetController().CanGoBack());
 
   // Close the popup.
@@ -1813,8 +1814,9 @@
     EXPECT_EQ(2, browser()->tab_strip_model()->count());
     new_popup = restored_tab_observer.GetWebContents();
   }
-  EXPECT_EQ(other_url, new_popup->GetMainFrame()->GetLastCommittedURL());
-  EXPECT_EQ(other_origin, new_popup->GetMainFrame()->GetLastCommittedOrigin());
+  EXPECT_EQ(other_url, new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(other_origin,
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   ASSERT_TRUE(new_popup->GetController().CanGoBack());
   int reopened_tab_index = browser()->tab_strip_model()->active_index();
   EXPECT_EQ(1, reopened_tab_index);
@@ -1822,9 +1824,9 @@
   // Navigate the popup back to about:blank.
   GoBack(browser());
   EXPECT_EQ(GURL(url::kAboutBlankURL),
-            new_popup->GetMainFrame()->GetLastCommittedURL());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_origin,
-            new_popup->GetMainFrame()->GetLastCommittedOrigin());
+            new_popup->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 // Ensures group IDs are regenerated for restored windows so that we don't split
diff --git a/chrome/browser/share/link_to_text_bridge.cc b/chrome/browser/share/link_to_text_bridge.cc
index f37be57..c36394b7 100644
--- a/chrome/browser/share/link_to_text_bridge.cc
+++ b/chrome/browser/share/link_to_text_bridge.cc
@@ -19,7 +19,7 @@
     const base::android::JavaParamRef<jobject>& j_web_contents) {
   content::WebContents* web_contents =
       content::WebContents::FromJavaWebContents(j_web_contents);
-  return web_contents->GetMainFrame()->GetPageUkmSourceId();
+  return web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 }
 }  // namespace
 
diff --git a/chrome/browser/shared_highlighting/shared_highlighting_browsertest.cc b/chrome/browser/shared_highlighting/shared_highlighting_browsertest.cc
index 61d62868..9ba11e8 100644
--- a/chrome/browser/shared_highlighting/shared_highlighting_browsertest.cc
+++ b/chrome/browser/shared_highlighting/shared_highlighting_browsertest.cc
@@ -175,7 +175,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->GetRemoteInterfaces()
       ->GetInterface(remote.BindNewPipeAndPassReceiver());
   remote->ExtractTextFragmentsMatches(
@@ -362,13 +362,13 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   // Intercept TextFragmentReceiver Mojo connection.
   MockTextFragmentReceiver text_fragment_receiver;
   service_manager::InterfaceProvider::TestApi interface_overrider(
-      web_contents()->GetMainFrame()->GetRemoteInterfaces());
+      web_contents()->GetPrimaryMainFrame()->GetRemoteInterfaces());
   interface_overrider.SetBinderForName(
       blink::mojom::TextFragmentReceiver::Name_,
       base::BindRepeating(&MockTextFragmentReceiver::Bind,
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_metrics.cc b/chrome/browser/sharing/click_to_call/click_to_call_metrics.cc
index 5683e12..d4c4b4c 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_metrics.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_metrics.cc
@@ -20,7 +20,8 @@
   if (!ukm_recorder)
     return;
 
-  ukm::SourceId source_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   if (source_id == ukm::kInvalidSourceId)
     return;
 
diff --git a/chrome/browser/signin/header_modification_delegate_impl.cc b/chrome/browser/signin/header_modification_delegate_impl.cc
index b31d350..10ba226 100644
--- a/chrome/browser/signin/header_modification_delegate_impl.cc
+++ b/chrome/browser/signin/header_modification_delegate_impl.cc
@@ -134,7 +134,7 @@
     return true;
 
   if (extensions::WebViewRendererState::GetInstance()->IsGuest(
-          contents->GetMainFrame()->GetProcess()->GetID())) {
+          contents->GetPrimaryMainFrame()->GetProcess()->GetID())) {
     auto identity_api_config =
         extensions::WebAuthFlow::GetWebViewPartitionConfig(
             extensions::WebAuthFlow::GET_AUTH_TOKEN,
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
index b5bf63a..8ebbcd5 100644
--- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -171,7 +171,7 @@
 
   content::RenderFrameHost* interstitial_frame_host;
 
-  interstitial_frame_host = active_web_contents->GetMainFrame();
+  interstitial_frame_host = active_web_contents->GetPrimaryMainFrame();
 
   EXPECT_EQ(SitePerProcessHighDPIExpiredCertBrowserTest::kDeviceScaleFactor,
             GetFrameDeviceScaleFactor(interstitial_frame_host));
@@ -203,7 +203,7 @@
 
   // Find the subframe's RenderFrameHost.
   content::RenderFrameHost* frame_host =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(frame_host);
   EXPECT_EQ(cross_site_url, frame_host->GetLastCommittedURL());
   EXPECT_TRUE(frame_host->IsCrossProcessSubframe());
@@ -601,9 +601,9 @@
       GURL(embedded_test_server()->GetURL("b.com", "/title1.html"))));
 
   content::RenderFrameHost* child_0 =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* child_1 =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 1);
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 1);
 
   // Add an unload handler that calls print() to child-0 iframe.
   EXPECT_TRUE(ExecuteScript(
@@ -660,7 +660,7 @@
   // Close the popup.  This should *not* kill the b.com process, as it still
   // has a pending navigation in the opener window.
   content::RenderProcessHost* b_com_rph =
-      popup_contents->GetMainFrame()->GetProcess();
+      popup_contents->GetPrimaryMainFrame()->GetProcess();
   content::WebContentsDestroyedWatcher destroyed_watcher(popup_contents);
   EXPECT_TRUE(ExecuteScript(popup_contents, "window.close();"));
   destroyed_watcher.Wait();
@@ -669,7 +669,8 @@
   // Resume the pending navigation in the original tab and ensure it finishes
   // loading successfully.
   manager.WaitForNavigationFinished();
-  EXPECT_EQ(b_url, opener_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(b_url,
+            opener_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 }
 
 #if defined(USE_AURA)
@@ -686,7 +687,7 @@
   GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
   content::RenderWidgetHostView* child_rwhv = child_frame->GetView();
   content::RenderWidgetHost* child_rwh = child_rwhv->GetRenderWidgetHost();
@@ -749,8 +750,9 @@
   // popup in its message handler, and the popup shouldn't be blocked.
   content::TestNavigationObserver popup_observer(nullptr);
   popup_observer.StartWatchingNewWebContents();
-  EXPECT_TRUE(ExecuteScript(ChildFrameAt(web_contents->GetMainFrame(), 0),
-                            "parent.postMessage('foo', '*')"));
+  EXPECT_TRUE(
+      ExecuteScript(ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0),
+                    "parent.postMessage('foo', '*')"));
   popup_observer.Wait();
   ASSERT_EQ(2, browser()->tab_strip_model()->count());
 
@@ -782,7 +784,7 @@
   GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   // Add a postMessage handler in the root frame.  The handler opens a new popup
   // for a URL constructed using postMessage event data.
@@ -832,7 +834,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* frame_b =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* frame_c = ChildFrameAt(frame_b, 0);
 
   // Add a postMessage handler in root_frame and frame_b.  The handler opens a
@@ -896,14 +898,15 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* grandchild = ChildFrameAt(child, 0);
   ASSERT_TRUE(child->IsCrossProcessSubframe());
   ASSERT_TRUE(grandchild->IsCrossProcessSubframe());
-  ASSERT_NE(child->GetProcess(), web_contents->GetMainFrame()->GetProcess());
+  ASSERT_NE(child->GetProcess(),
+            web_contents->GetPrimaryMainFrame()->GetProcess());
   ASSERT_NE(grandchild->GetProcess(), child->GetProcess());
   ASSERT_NE(grandchild->GetProcess(),
-            web_contents->GetMainFrame()->GetProcess());
+            web_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Add a postMessage handler to middle frame to send another postMessage to
   // top frame and then immediately attempt window.open().
@@ -962,7 +965,7 @@
   GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   // Add a postMessage handler in the root frame.  The handler opens a new popup
   // for a URL constructed using postMessage event data.
@@ -1018,7 +1021,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* frame_b =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* frame_c = ChildFrameAt(frame_b, 0);
 
   // Activate frame_b by executing a dummy script.
@@ -1076,9 +1079,9 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* frame_b =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* frame_c =
-      ChildFrameAt(web_contents->GetMainFrame(), 1);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 1);
 
   // Activate frame_b and frame_c by executing dummy scripts.
   const std::string no_op_script = "// No-op script";
@@ -1204,7 +1207,7 @@
 
   // Install a dialog-showing beforeunload handler in the iframe.
   content::RenderFrameHost* child =
-      ChildFrameAt(second_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(second_web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
   content::PrepContentsForBeforeUnloadTest(second_web_contents);
@@ -1252,9 +1255,9 @@
       tab_strip_model->GetActiveWebContents();
   EXPECT_NE(first_web_contents, second_web_contents);
   content::RenderFrameHost* child =
-      ChildFrameAt(second_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(second_web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(child->GetSiteInstance(),
-            second_web_contents->GetMainFrame()->GetSiteInstance());
+            second_web_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Install a dialog-showing beforeunload handler in the iframe.
   EXPECT_TRUE(
@@ -1321,7 +1324,7 @@
 
   // Install a dialog-showing beforeunload handler in the iframe.
   content::RenderFrameHost* child =
-      ChildFrameAt(second_web_contents->GetMainFrame(), 0);
+      ChildFrameAt(second_web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
   content::PrepContentsForBeforeUnloadTest(second_web_contents);
@@ -1378,7 +1381,7 @@
 
   // Install a dialog-showing beforeunload handler in the second iframe.
   content::RenderFrameHost* child =
-      ChildFrameAt(second_web_contents->GetMainFrame(), 1);
+      ChildFrameAt(second_web_contents->GetPrimaryMainFrame(), 1);
   EXPECT_TRUE(
       ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
   content::PrepContentsForBeforeUnloadTest(second_web_contents);
@@ -1427,7 +1430,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* frame_a =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* frame_b = ChildFrameAt(frame_a, 0);
 
   // The test becomes flaky if we don't wait for frame_a's hit-test data before
@@ -1477,7 +1480,7 @@
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderProcessHostWatcher watcher(
-      contents->GetMainFrame()->GetProcess(),
+      contents->GetPrimaryMainFrame()->GetProcess(),
       content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
 
   // This file will attempt a cross-process navigation.
diff --git a/chrome/browser/site_isolation/isolated_sandboxed_iframe_browsertest.cc b/chrome/browser/site_isolation/isolated_sandboxed_iframe_browsertest.cc
index a54cb56..0b1c1a0 100644
--- a/chrome/browser/site_isolation/isolated_sandboxed_iframe_browsertest.cc
+++ b/chrome/browser/site_isolation/isolated_sandboxed_iframe_browsertest.cc
@@ -194,7 +194,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame_host = web_contents->GetPrimaryMainFrame();
 
   VerifyStartupMetrics();
 
@@ -229,7 +229,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame_host = web_contents->GetPrimaryMainFrame();
 
   VerifyStartupMetrics();
 
@@ -269,7 +269,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame_host = web_contents->GetPrimaryMainFrame();
 
   VerifyStartupMetrics();
 
@@ -313,7 +313,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url_a));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame_host = web_contents->GetPrimaryMainFrame();
 
   VerifyStartupMetrics();
 
@@ -344,7 +344,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         child_url_b.spec().c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents_b->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents_b->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents_b));
   }
 
@@ -376,7 +376,7 @@
         "frame.srcdoc = '%s'; "
         "document.body.appendChild(frame);",
         child_inner_text.c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -408,7 +408,7 @@
         "frame.sandbox = ''; "
         "frame.src = 'about:blank'; "
         "document.body.appendChild(frame);");
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -442,7 +442,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         empty_url.spec().c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -476,7 +476,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         js_url_str.c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -510,7 +510,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         child_url.spec().c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -544,7 +544,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         child_url.spec().c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
@@ -552,7 +552,7 @@
   // is isolatable. We make sure the popup url is same-site to the opener,
   // otherwise it would just create an OOPIF.
   content::RenderFrameHost* child_rfh =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   {
     std::string js_str =
         base::StringPrintf("window.open('%s');", popup_url.spec().c_str());
@@ -594,7 +594,7 @@
 
     content::TestNavigationObserver popup_observer(nullptr);
     popup_observer.StartWatchingNewWebContents();
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     popup_observer.Wait();
   }
 
@@ -645,7 +645,7 @@
         "frame.src = '%s'; "
         "document.body.appendChild(frame);",
         data_url_str.c_str());
-    EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), js_str));
+    EXPECT_TRUE(ExecuteScript(web_contents->GetPrimaryMainFrame(), js_str));
     ASSERT_TRUE(WaitForLoadStop(web_contents));
   }
 
diff --git a/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc b/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc
index 96d5bae..2795cc73 100644
--- a/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc
+++ b/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc
@@ -397,7 +397,7 @@
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url));
 
   // Make sure we got two SiteInstances.
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   auto* child_frame = ChildFrameAt(main_frame, 0);
   EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
 
@@ -426,7 +426,7 @@
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url));
 
   // Make sure we got two SiteInstances.
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   auto* child_frame = ChildFrameAt(main_frame, 0);
   EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
 
@@ -455,7 +455,7 @@
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url));
 
   // Make sure we got two SiteInstances.
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   auto* child_frame = ChildFrameAt(main_frame, 0);
   EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
 
@@ -483,7 +483,7 @@
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url));
 
   // Make sure we got two SiteInstances.
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   auto* child_frame = ChildFrameAt(main_frame, 0);
   EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
 
diff --git a/chrome/browser/site_isolation/site_details_browsertest.cc b/chrome/browser/site_isolation/site_details_browsertest.cc
index 6688543..48e9303f 100644
--- a/chrome/browser/site_isolation/site_details_browsertest.cc
+++ b/chrome/browser/site_isolation/site_details_browsertest.cc
@@ -902,7 +902,7 @@
       embedded_test_server()->GetURL("b.com", "/fenced_frames/iframe.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails();
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
index d568be4..3c2933b 100644
--- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
+++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -137,7 +137,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
   ASSERT_NE(nullptr, child1);
   content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
@@ -208,7 +208,7 @@
   // Focus the subframe and then its input field.  The return value
   // "input-focus" will be sent once the input field's focus event fires.
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   std::string result;
   std::string script =
       "function onInput(e) {"
@@ -272,7 +272,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
   ASSERT_NE(nullptr, child1);
   content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
@@ -360,7 +360,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
 
   content::TestNavigationObserver observer(web_contents);
   GURL object_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
@@ -441,7 +441,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
   ASSERT_NE(nullptr, child1);
   content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
@@ -764,7 +764,7 @@
       embedded_test_server()->GetURL("b.com", "/fullscreen_frame.html"));
   EXPECT_TRUE(NavigateIframeToURL(web_contents, "child-0", frame_url));
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
   gfx::Size original_child_size = GetFrameSize(child);
 
@@ -847,7 +847,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
   content::RenderFrameHost* grandchild = ChildFrameAt(child, 0);
 
@@ -994,7 +994,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* a_top = web_contents->GetMainFrame();
+  content::RenderFrameHost* a_top = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* a_bottom = ChildFrameAt(a_top, 0);
   content::RenderFrameHost* b_first = ChildFrameAt(a_bottom, 0);
   content::RenderFrameHost* b_second = ChildFrameAt(a_bottom, 1);
@@ -1120,7 +1120,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
 
   EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
@@ -1249,7 +1249,7 @@
   navigation_observer.Wait();
 
   content::RenderWidgetHostView* child_view =
-      ChildFrameAt(active_web_contents->GetMainFrame(), 0)->GetView();
+      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0)->GetView();
 
   ContextMenuWaiter menu_waiter;
 
@@ -1298,7 +1298,8 @@
 
   // Make sure the text area is focused. First, we must explicitly focus the
   // child iframe containing the text area.
-  content::RenderFrameHost* main_frame = embedder_web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame =
+      embedder_web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_text_area = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(content::ExecJs(child_text_area, "window.focus();"));
   bool starts_focused =
@@ -1479,8 +1480,12 @@
   GURL main_url(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(b)"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
-  content::RenderFrameHost* child_frame = ChildFrameAt(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 0);
+  content::RenderFrameHost* child_frame =
+      ChildFrameAt(browser()
+                       ->tab_strip_model()
+                       ->GetActiveWebContents()
+                       ->GetPrimaryMainFrame(),
+                   0);
 
   // Add <input type='date'> to the child frame. Adjust the positions that we
   // know where to click to dismiss the popup.
@@ -1606,7 +1611,8 @@
   // Verify that the new content has loaded the expected contents.
   GURL target_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
   EXPECT_TRUE(WaitForLoadStop(new_contents));
-  EXPECT_EQ(target_url, new_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(target_url,
+            new_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   // Verify that the anchor opened in a new background tab.
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
diff --git a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc
index d74a03e..96133ab 100644
--- a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc
+++ b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc
@@ -364,7 +364,8 @@
   // inside frame. For example, for 'a(b(c, d(e)))', [0] returns b, and
   // [0, 1, 0] returns e;
   content::RenderFrameHost* GetFrame(const IndexVector& indices) {
-    content::RenderFrameHost* current = active_contents()->GetMainFrame();
+    content::RenderFrameHost* current =
+        active_contents()->GetPrimaryMainFrame();
     for (size_t index : indices)
       current = ChildFrameAt(current, index);
     return current;
@@ -1159,7 +1160,7 @@
   // Focus the subframe and then its input field.  The return value
   // "input-focus" will be sent once the input field's focus event fires.
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   std::string result;
   std::string script =
       "function onInput(e) {"
diff --git a/chrome/browser/site_isolation/spellcheck_per_process_browsertest.cc b/chrome/browser/site_isolation/spellcheck_per_process_browsertest.cc
index 7ee71f4..ae07547 100644
--- a/chrome/browser/site_isolation/spellcheck_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/spellcheck_per_process_browsertest.cc
@@ -295,7 +295,7 @@
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     content::RenderFrameHost* cross_site_subframe =
-        ChildFrameAt(web_contents->GetMainFrame(), 0);
+        ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
     MockSpellCheckHost* spell_check_host =
         spell_check_helper.GetSpellCheckHostForProcess(
@@ -330,7 +330,7 @@
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     content::RenderFrameHost* cross_site_subframe =
-        ChildFrameAt(web_contents->GetMainFrame(), 0);
+        ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
     MockSpellCheckHost* spell_check_host =
         spell_check_helper.GetSpellCheckHostForProcess(
@@ -370,7 +370,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* cross_site_subframe =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
 
   EXPECT_TRUE(cross_site_subframe->IsCrossProcessSubframe());
 
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc
index dfb3e33..30f4819 100644
--- a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc
+++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc
@@ -69,7 +69,7 @@
   extensions::ExtensionHost* host =
       extensions::ProcessManager::Get(profile)->GetBackgroundHostForExtension(
           extension_id);
-  host->host_contents()->GetMainFrame()->AddMessageToConsole(
+  host->host_contents()->GetPrimaryMainFrame()->AddMessageToConsole(
       blink::mojom::ConsoleMessageLevel::kWarning,
       constants::kErrorMissingPauseOrResume);
 }
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index 62792e87..15a57ba 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -516,7 +516,7 @@
   content::RenderProcessHost* process = browser()
                                             ->tab_strip_model()
                                             ->GetActiveWebContents()
-                                            ->GetMainFrame()
+                                            ->GetPrimaryMainFrame()
                                             ->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
diff --git a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
index 7efc3fa7..d054771 100644
--- a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
+++ b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
@@ -253,7 +253,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), GURL("https://mock.failed.request/start=-20")));
   content::RenderFrameHost* frame;
-  frame = contents->GetMainFrame();
+  frame = contents->GetPrimaryMainFrame();
   ASSERT_TRUE(WaitForRenderFrameReady(frame));
 
   EXPECT_EQ(expect_wifi == EXPECT_WIFI_YES,
diff --git a/chrome/browser/ssl/crlset_browsertest.cc b/chrome/browser/ssl/crlset_browsertest.cc
index 7dea5157..ec930b6 100644
--- a/chrome/browser/ssl/crlset_browsertest.cc
+++ b/chrome/browser/ssl/crlset_browsertest.cc
@@ -93,7 +93,8 @@
   ASSERT_EQ(interstitial_expected,
             chrome_browser_interstitials::IsShowingInterstitial(
                 GetActiveWebContents()));
-  ASSERT_TRUE(WaitForRenderFrameReady(GetActiveWebContents()->GetMainFrame()));
+  ASSERT_TRUE(
+      WaitForRenderFrameReady(GetActiveWebContents()->GetPrimaryMainFrame()));
 
   if (interstitial_expected) {
     ASSERT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(
@@ -138,7 +139,8 @@
   ASSERT_EQ(interstitial_expected,
             chrome_browser_interstitials::IsShowingInterstitial(
                 GetActiveWebContents()));
-  ASSERT_TRUE(WaitForRenderFrameReady(GetActiveWebContents()->GetMainFrame()));
+  ASSERT_TRUE(
+      WaitForRenderFrameReady(GetActiveWebContents()->GetPrimaryMainFrame()));
 
   if (interstitial_expected) {
     ASSERT_TRUE(
@@ -244,7 +246,8 @@
 
   ASSERT_TRUE(chrome_browser_interstitials::IsShowingInterstitial(
       GetActiveWebContents()));
-  ASSERT_TRUE(WaitForRenderFrameReady(GetActiveWebContents()->GetMainFrame()));
+  ASSERT_TRUE(
+      WaitForRenderFrameReady(GetActiveWebContents()->GetPrimaryMainFrame()));
 
   ssl_test_util::CheckSecurityState(
       GetActiveWebContents(),
@@ -257,5 +260,5 @@
 
   // Expect there to be a proceed link, even for HSTS.
   EXPECT_TRUE(chrome_browser_interstitials::InterstitialHasProceedLink(
-      GetActiveWebContents()->GetMainFrame()));
+      GetActiveWebContents()->GetPrimaryMainFrame()));
 }
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
index eeb1fe8e..c64343f 100644
--- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -146,7 +146,7 @@
   // Any frame in the active page might have a password field, so inject scripts
   // into all of them to ensure that notifications from all of them have been
   // sent.
-  contents->GetMainFrame()->ForEachRenderFrameHost(
+  contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
       base::BindRepeating([](content::RenderFrameHost* frame) {
         bool js_result = false;
         EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
@@ -1777,7 +1777,7 @@
       https_server_.GetURL("/ssl/page_displays_insecure_content.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   if (IsAutoupgradeEnabled()) {
@@ -1814,7 +1814,7 @@
 
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
   // Check that nothing has been loaded in the fenced frame.
   EXPECT_EQ(
diff --git a/chrome/browser/ssl/security_state_tab_helper_unittest.cc b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
index e47a6b965..b1f9981 100644
--- a/chrome/browser/ssl/security_state_tab_helper_unittest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
@@ -64,7 +64,7 @@
 
   void StartNavigation(bool is_form, bool is_main_frame) {
     testing::NiceMock<MockNavigationHandle> handle(
-        GURL("http://example.test"), web_contents()->GetMainFrame());
+        GURL("http://example.test"), web_contents()->GetPrimaryMainFrame());
     handle.set_is_form_submission(is_form);
     handle.set_is_in_main_frame(is_main_frame);
     helper_->DidStartNavigation(&handle);
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 85cc368..4518e1d 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -392,7 +392,7 @@
 void ExpectInterstitialElementHidden(WebContents* tab,
                                      const std::string& element_id,
                                      bool expect_hidden) {
-  content::RenderFrameHost* frame = tab->GetMainFrame();
+  content::RenderFrameHost* frame = tab->GetPrimaryMainFrame();
   // Send CMD_TEXT_FOUND to indicate that the 'hidden' class is found, and
   // CMD_TEXT_NOT_FOUND if not.
   std::string command = base::StringPrintf(
@@ -2653,8 +2653,8 @@
   observer.Wait();
 
   // Both tabs should have the same process.
-  EXPECT_EQ(tab1->GetMainFrame()->GetProcess(),
-            tab2->GetMainFrame()->GetProcess());
+  EXPECT_EQ(tab1->GetPrimaryMainFrame()->GetProcess(),
+            tab2->GetPrimaryMainFrame()->GetProcess());
 
   // The new tab has insecure content.
   ssl_test_util::CheckAuthenticationBrokenState(
@@ -3398,7 +3398,7 @@
 
     EXPECT_EQ(expected_show_blocked,
               content_settings::PageSpecificContentSettings::GetForFrame(
-                  tab->GetMainFrame())
+                  tab->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::MIXEDSCRIPT));
     ssl_test_util::CheckSecurityState(
         tab, CertError::NONE,
@@ -3407,8 +3407,8 @@
         expected_show_dangerous ? AuthState::RAN_INSECURE_CONTENT
                                 : AuthState::NONE);
     // Clears title.
-    ASSERT_TRUE(
-        content::ExecuteScript(tab->GetMainFrame(), "document.title = \"\";"));
+    ASSERT_TRUE(content::ExecuteScript(tab->GetPrimaryMainFrame(),
+                                       "document.title = \"\";"));
 
     {
       // SetAllowRunningInsecureContent will reload the page.
@@ -3422,7 +3422,7 @@
 
     EXPECT_EQ(expected_show_blocked_after_allow,
               content_settings::PageSpecificContentSettings::GetForFrame(
-                  tab->GetMainFrame())
+                  tab->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::MIXEDSCRIPT));
     ssl_test_util::CheckSecurityState(
         tab, CertError::NONE,
@@ -3438,8 +3438,10 @@
 
  private:
   void SetAllowRunningInsecureContent() {
-    content::RenderFrameHost* render_frame_host =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* render_frame_host = browser()
+                                                      ->tab_strip_model()
+                                                      ->GetActiveWebContents()
+                                                      ->GetPrimaryMainFrame();
     mojo::AssociatedRemote<content_settings::mojom::ContentSettingsAgent> agent;
     render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&agent);
     agent->SetAllowRunningInsecureContent();
@@ -3448,7 +3450,7 @@
   void CheckErrorStateIsCleared() {
     WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
     EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                     tab->GetMainFrame())
+                     tab->GetPrimaryMainFrame())
                      ->IsContentBlocked(ContentSettingsType::MIXEDSCRIPT));
     ssl_test_util::CheckSecurityState(tab, CertError::NONE,
                                       security_state::NONE, AuthState::NONE);
@@ -4078,7 +4080,7 @@
   ASSERT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(tab));
 
   EXPECT_TRUE(chrome_browser_interstitials::InterstitialHasProceedLink(
-      tab->GetMainFrame()));
+      tab->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestLearnMoreLinkContainsErrorCode) {
@@ -4122,7 +4124,7 @@
   observer.Wait();
 
   content::RenderFrameHost* child =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
   int result = security_interstitials::CMD_ERROR;
   const std::string javascript = base::StringPrintf(
@@ -4161,7 +4163,7 @@
       "? (%d) : (%d))",
       security_interstitials::CMD_TEXT_NOT_FOUND,
       security_interstitials::CMD_TEXT_FOUND);
-  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(tab->GetMainFrame(),
+  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(tab->GetPrimaryMainFrame(),
                                                   javascript, &result));
   EXPECT_EQ(security_interstitials::CMD_TEXT_NOT_FOUND, result);
 }
@@ -7261,9 +7263,9 @@
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), expected_explanation));
+      tab->GetPrimaryMainFrame(), expected_explanation));
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), expected_primary_paragraph));
+      tab->GetPrimaryMainFrame(), expected_primary_paragraph));
 }
 
 // Tests that the correct strings are displayed on the interstitial in the
@@ -7284,7 +7286,7 @@
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText(
-      tab->GetMainFrame(), expected_explanation));
+      tab->GetPrimaryMainFrame(), expected_explanation));
 }
 
 // Initialize MITMSoftware certificate list but set the version_id to zero. This
@@ -7315,7 +7317,7 @@
 
   EXPECT_EQ(net::OK,
             content::LoadBasicRequest(
-                tab->GetMainFrame(),
+                tab->GetPrimaryMainFrame(),
                 https_server_mismatched_.GetURL("/anchor_download_test.png")));
 }
 
@@ -8356,9 +8358,11 @@
 
   // Navigate to site with an insecure form and submit it in a fenced frame.
   content::RenderFrameHost* fenced_frame =
-      fenced_frame_test_helper().CreateFencedFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-          form_site_url);
+      fenced_frame_test_helper().CreateFencedFrame(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                   form_site_url);
   ASSERT_TRUE(fenced_frame);
   content::TestNavigationObserver observer(GetWebContents());
   content::WebContentsConsoleObserver console_observer(GetWebContents());
diff --git a/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc b/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc
index 070e66d..3231dfe 100644
--- a/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc
+++ b/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc
@@ -44,7 +44,7 @@
   }
 
   RenderFrameHost* primary_main_frame_host() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   WebContents* web_contents() {
@@ -116,7 +116,7 @@
 
   // Create a fenced frame and navigate to the allowlisted url.
   RenderFrameHost* fenced_frame_rfh = fenced_frame_helper_.CreateFencedFrame(
-      app_contents->GetMainFrame(), allow_url);
+      app_contents->GetPrimaryMainFrame(), allow_url);
   ASSERT_NE(nullptr, fenced_frame_rfh);
   // Ensure that the interstitial isn't shown for the fenced frame in the app.
   EXPECT_FALSE(IsShowingSSLInterstitial(app_contents));
diff --git a/chrome/browser/ssl/ssl_prerender_browsertest.cc b/chrome/browser/ssl/ssl_prerender_browsertest.cc
index 12c231b8..bc95fa898 100644
--- a/chrome/browser/ssl/ssl_prerender_browsertest.cc
+++ b/chrome/browser/ssl/ssl_prerender_browsertest.cc
@@ -317,7 +317,7 @@
 
     // Activate.
     ASSERT_TRUE(
-        content::ExecJs(web_contents()->GetMainFrame(),
+        content::ExecJs(web_contents()->GetPrimaryMainFrame(),
                         content::JsReplace("location = $1", kPrerenderUrl)));
     activation_manager.WaitForNavigationFinished();
     EXPECT_TRUE(activation_manager.was_activated());
diff --git a/chrome/browser/storage/durable_storage_browsertest.cc b/chrome/browser/storage/durable_storage_browsertest.cc
index f8a38494..c85df7f 100644
--- a/chrome/browser/storage/durable_storage_browsertest.cc
+++ b/chrome/browser/storage/durable_storage_browsertest.cc
@@ -41,7 +41,9 @@
 
  protected:
   content::RenderFrameHost* GetRenderFrameHost(Browser* browser) {
-    return browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
   content::RenderFrameHost* GetRenderFrameHost() {
diff --git a/chrome/browser/storage/durable_storage_permission_context_unittest.cc b/chrome/browser/storage/durable_storage_permission_context_unittest.cc
index e68e9797..083d40a8 100644
--- a/chrome/browser/storage/durable_storage_permission_context_unittest.cc
+++ b/chrome/browser/storage/durable_storage_permission_context_unittest.cc
@@ -94,8 +94,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -120,8 +120,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -148,8 +148,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -172,8 +172,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -203,8 +203,8 @@
   cookie_settings->SetCookieSetting(url, CONTENT_SETTING_BLOCK);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
@@ -229,8 +229,8 @@
   NavigateAndCommit(url);
 
   const permissions::PermissionRequestID id(
-      web_contents()->GetMainFrame()->GetProcess()->GetID(),
-      web_contents()->GetMainFrame()->GetRoutingID(),
+      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetPrimaryMainFrame()->GetRoutingID(),
       permissions::PermissionRequestID::RequestLocalId());
 
   ASSERT_EQ(0, permission_context.permission_set_count());
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc
index f5c3d25..911b885d 100644
--- a/chrome/browser/storage_access_api/api_browsertest.cc
+++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -123,14 +123,14 @@
     storage::test::ExpectFrameContent(GetNestedFrame(), expected);
   }
 
-  content::RenderFrameHost* GetMainFrame() {
+  content::RenderFrameHost* GetPrimaryMainFrame() {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   }
 
   content::RenderFrameHost* GetFrame() {
-    return ChildFrameAt(GetMainFrame(), 0);
+    return ChildFrameAt(GetPrimaryMainFrame(), 0);
   }
 
   content::RenderFrameHost* GetNestedFrame() {
@@ -477,7 +477,7 @@
 
   NavigateToPageWithFrame("a.com");
   ASSERT_TRUE(ExecuteScript(
-      GetMainFrame(),
+      GetPrimaryMainFrame(),
       "document.querySelector('iframe').sandbox='allow-scripts';"));
   NavigateFrameTo("b.com", "/echoheader?cookie");
 
@@ -491,7 +491,7 @@
   SetBlockThirdPartyCookies(true);
 
   NavigateToPageWithFrame("a.com");
-  ASSERT_TRUE(ExecuteScript(GetMainFrame(),
+  ASSERT_TRUE(ExecuteScript(GetPrimaryMainFrame(),
                             "document.querySelector('iframe').sandbox='allow-"
                             "scripts allow-same-origin';"));
   NavigateFrameTo("b.com", "/echoheader?cookie");
@@ -506,7 +506,7 @@
 
   NavigateToPageWithFrame("a.com");
   ASSERT_TRUE(ExecuteScript(
-      GetMainFrame(),
+      GetPrimaryMainFrame(),
       "document.querySelector('iframe').sandbox='allow-scripts "
       "allow-same-origin allow-storage-access-by-user-activation';"));
   NavigateFrameTo("b.com", "/echoheader?cookie");
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
index 34918a79..3c7f942 100644
--- a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
+++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
@@ -88,7 +88,8 @@
 
   permissions::PermissionRequestID CreateFakeID() {
     return permissions::PermissionRequestID(
-        web_contents()->GetMainFrame(), request_id_generator_.GenerateNextId());
+        web_contents()->GetPrimaryMainFrame(),
+        request_id_generator_.GenerateNextId());
   }
 
  private:
diff --git a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
index cf55036..a58c5c1 100644
--- a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
+++ b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
@@ -348,7 +348,7 @@
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GetURL("frame_factory.html")));
   EXPECT_FALSE(observer.GetIsAdSubframe(
-      GetWebContents()->GetMainFrame()->GetFrameTreeNodeId()));
+      GetWebContents()->GetPrimaryMainFrame()->GetFrameTreeNodeId()));
 
   // (1) Vanilla child.
   content::RenderFrameHost* vanilla_child =
@@ -1121,7 +1121,9 @@
     return observer_->GetIsAdSubframe(host->GetFrameTreeNodeId());
   }
 
-  RenderFrameHost* PrimaryMainFrame() { return web_contents()->GetMainFrame(); }
+  RenderFrameHost* PrimaryMainFrame() {
+    return web_contents()->GetPrimaryMainFrame();
+  }
 
   GURL GetURL(const std::string& page) {
     return https_server_.GetURL("/ad_tagging/" + page);
diff --git a/chrome/browser/subresource_filter/ads_intervention_manager_browsertest.cc b/chrome/browser/subresource_filter/ads_intervention_manager_browsertest.cc
index 9c54866..edf41ef 100644
--- a/chrome/browser/subresource_filter/ads_intervention_manager_browsertest.cc
+++ b/chrome/browser/subresource_filter/ads_intervention_manager_browsertest.cc
@@ -63,7 +63,8 @@
   // Should not trigger activation as the URL is not on the blocklist and
   // has no active ads interventions.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
@@ -77,11 +78,12 @@
   // Trigger an ads violation and renavigate the page. Should trigger
   // subresource filter activation.
   current_throttle_manager()->OnAdsViolationTriggered(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       mojom::AdsViolation::kMobileAdDensityByHeightAbove30);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 1);
@@ -107,7 +109,8 @@
   test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kAdsInterventionRecordedHistogram,
       static_cast<int>(mojom::AdsViolation::kMobileAdDensityByHeightAbove30),
@@ -148,7 +151,8 @@
   // Should not trigger activation as the URL is not on the blocklist and
   // has no active ads interventions.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
@@ -162,11 +166,12 @@
   // Trigger an ads violation and renavigate the page. Should trigger
   // subresource filter activation.
   current_throttle_manager()->OnAdsViolationTriggered(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       mojom::AdsViolation::kMobileAdDensityByHeightAbove30);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 1);
@@ -193,7 +198,7 @@
   test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get() -
                       base::Minutes(30));
   current_throttle_manager()->OnAdsViolationTriggered(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       mojom::AdsViolation::kMobileAdDensityByHeightAbove30);
 
   // Advance the clock to to kAdsInterventionDuration from the first
@@ -201,7 +206,8 @@
   test_clock->Advance(base::Minutes(30));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kAdsInterventionRecordedHistogram,
       static_cast<int>(mojom::AdsViolation::kMobileAdDensityByHeightAbove30),
@@ -259,7 +265,8 @@
   // Should not trigger activation as the URL is not on the blocklist and
   // has no active ads interventions.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
@@ -270,14 +277,15 @@
   // Trigger an ads violation and renavigate to the page. Interventions are not
   // enforced so no activation should occur.
   current_throttle_manager()->OnAdsViolationTriggered(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       mojom::AdsViolation::kMobileAdDensityByHeightAbove30);
 
   const base::TimeDelta kRenavigationDelay = base::Hours(2);
   test_clock->Advance(kRenavigationDelay);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
       subresource_filter::SubresourceFilterAction::kUIShown, 0);
diff --git a/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc
index 013fbae..041e4402 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc
@@ -187,7 +187,7 @@
   for (size_t i = 0; i < frame_names.size(); ++i) {
     SCOPED_TRACE(frame_names[i]);
     int client_width =
-        content::EvalJs(web_contents()->GetMainFrame(),
+        content::EvalJs(web_contents()->GetPrimaryMainFrame(),
                         base::StringPrintf(kScript, frame_names[i]))
             .ExtractInt();
     EXPECT_EQ(expect_displayed[i], !!client_width) << client_width;
@@ -203,7 +203,7 @@
 }
 
 void SubresourceFilterBrowserTest::InsertDynamicFrameWithScript() {
-  EXPECT_EQ(true, content::EvalJs(web_contents()->GetMainFrame(),
+  EXPECT_EQ(true, content::EvalJs(web_contents()->GetPrimaryMainFrame(),
                                   "insertFrameWithScriptAndNotify()",
                                   content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
 }
@@ -211,7 +211,7 @@
 void SubresourceFilterBrowserTest::NavigateFromRendererSide(const GURL& url) {
   content::TestNavigationObserver navigation_observer(web_contents(), 1);
   ASSERT_TRUE(content::ExecJs(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       base::StringPrintf("window.location = \"%s\";", url.spec().c_str())));
   navigation_observer.Wait();
 }
@@ -220,7 +220,7 @@
                                                  const GURL& url) {
   content::TestNavigationObserver navigation_observer(web_contents(), 1);
   ASSERT_TRUE(content::ExecJs(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       base::StringPrintf("document.getElementsByName(\"%s\")[0].src = \"%s\";",
                          frame_name, url.spec().c_str())));
   navigation_observer.Wait();
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
index bda27ed..c2f740e6 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -120,19 +120,22 @@
   ResetConfiguration(std::move(config));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   ASSERT_NO_FATAL_FAILURE(
       SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   EXPECT_FALSE(console_observer.messages().empty());
 
   // The main frame document should never be filtered.
   SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterListInsertingBrowserTest,
@@ -151,7 +154,8 @@
   ResetConfiguration(std::move(config));
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   ASSERT_EQ(1u, console_observer.messages().size());
   EXPECT_EQ(kActivationWarningConsoleMessage,
             console_observer.GetMessageAt(0u));
@@ -159,7 +163,8 @@
   ASSERT_NO_FATAL_FAILURE(
       SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   ASSERT_EQ(2u, console_observer.messages().size());
   EXPECT_EQ(kActivationWarningConsoleMessage,
@@ -207,19 +212,22 @@
   ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix(
       "suffix-that-does-not-match-anything"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   ASSERT_NO_FATAL_FAILURE(
       SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   EXPECT_FALSE(console_observer.messages().empty());
 
   // The main frame document should never be filtered.
   SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 // There should be no document-level de-/reactivation happening on the renderer
@@ -240,7 +248,8 @@
   ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix(
       "suffix-that-does-not-match-anything"));
   NavigateFromRendererSide(GetURLWithFragment(url, "ref"));
-  EXPECT_FALSE(IsDynamicScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      IsDynamicScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, SubFrameActivation) {
@@ -543,7 +552,8 @@
   // Verify that the ruleset persisted in the previous session is used for this
   // page load right after start-up.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest,
@@ -1092,14 +1102,16 @@
 
   base::HistogramTester tester;
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   content::TestNavigationObserver observer(
       browser()->tab_strip_model()->GetActiveWebContents(),
       content::MessageLoopRunner::QuitMode::DEFERRED);
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   observer.Wait();
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   tester.ExpectTotalCount(kActivationDecision, 2);
   tester.ExpectBucketCount(kActivationDecision,
diff --git a/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc
index 0523dee..4e04490d 100644
--- a/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_devtools_browsertest.cc
@@ -88,7 +88,8 @@
 
   // Should not trigger activation, the URL is not on the blocklist.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // Open up devtools and trigger forced activation.
   {
@@ -96,12 +97,14 @@
     devtools.EnableAdBlocking(true);
 
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_FALSE(
+        WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
     // Close devtools, should stop forced activation.
   }
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterListInsertingBrowserTest,
@@ -120,7 +123,8 @@
 
   // Should not trigger activation, the URL is not on the blocklist.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kActivationWarningConsoleMessage);
@@ -130,14 +134,16 @@
     ScopedDevtoolsOpener devtools(web_contents());
     devtools.EnableAdBlocking(true);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-    EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_FALSE(
+        WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
     console_observer.Wait();
     EXPECT_EQ(kActivationWarningConsoleMessage,
               console_observer.GetMessageAt(0u));
     // Close devtools, should stop forced activation.
   }
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterDevtoolsBrowserTest,
@@ -152,7 +158,8 @@
   devtools.EnableAdBlocking(true);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   EXPECT_FALSE(console_observer.messages().empty());
 }
 
@@ -180,7 +187,8 @@
   const GURL frame_with_script =
       GetTestUrl("subresource_filter/frame_with_included_script.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), frame_with_script));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   const GURL cross_site_frames = embedded_test_server()->GetURL(
       "a.com", "/subresource_filter/frame_cross_site_set.html");
@@ -194,7 +202,8 @@
   }
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), frame_with_script));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 }  // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_dns_alias_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_dns_alias_browsertest.cc
index 649a5b76..2971f240 100644
--- a/chrome/browser/subresource_filter/subresource_filter_dns_alias_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_dns_alias_browsertest.cc
@@ -139,7 +139,7 @@
   EXPECT_TRUE(NavigateToURL(web_contents, url));
 
   content::RenderFrameHost* child_rfh =
-      ChildFrameAt(web_contents->GetMainFrame(), 0u);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0u);
 
   if (level == ActivationLevel::kEnabled)
     EXPECT_FALSE(WasParsedScriptElementLoaded(child_rfh));
@@ -194,9 +194,9 @@
 
   EXPECT_TRUE(NavigateToURL(web_contents, url));
 
-  content::RenderFrameHost* main_rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_rfh = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_rfh =
-      ChildFrameAt(web_contents->GetMainFrame(), 0u);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0u);
 
   if (level == ActivationLevel::kEnabled) {
     EXPECT_EQ(GURL(), child_rfh->GetLastCommittedURL());
diff --git a/chrome/browser/subresource_filter/subresource_filter_fenced_frame_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_fenced_frame_browsertest.cc
index 18b4983..7d658a4 100644
--- a/chrome/browser/subresource_filter/subresource_filter_fenced_frame_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_fenced_frame_browsertest.cc
@@ -58,7 +58,7 @@
                           {safe_browsing::SubresourceFilterType::BETTER_ADS});
   RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_EQ(0u, console_observer.messages().size());
 
   // Navigate the fenced frame again.
@@ -87,8 +87,8 @@
   // collapsed.
   RenderFrameHost* fenced_frame_root =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kUrlWithAllowedScript);
-  EXPECT_EQ("300x150", EvalJs(web_contents()->GetMainFrame(), R"JS(
+          web_contents()->GetPrimaryMainFrame(), kUrlWithAllowedScript);
+  EXPECT_EQ("300x150", EvalJs(web_contents()->GetPrimaryMainFrame(), R"JS(
     let ff = document.querySelector('fencedframe');
     `${ff.clientWidth}x${ff.clientHeight}`;
   )JS"));
@@ -97,7 +97,7 @@
       fenced_frame_root, kUrlWithIncludedScript,
       /*expected_error_code=*/net::ERR_ABORTED);
 
-  EXPECT_EQ("0x0", EvalJs(web_contents()->GetMainFrame(), R"JS(
+  EXPECT_EQ("0x0", EvalJs(web_contents()->GetPrimaryMainFrame(), R"JS(
     let ff = document.querySelector('fencedframe');
     `${ff.clientWidth}x${ff.clientHeight}`;
   )JS"));
@@ -106,7 +106,7 @@
   fenced_frame_root = fenced_frame_test_helper().NavigateFrameInFencedFrameTree(
       fenced_frame_root, kUrlWithAllowedScript);
 
-  EXPECT_EQ("300x150", EvalJs(web_contents()->GetMainFrame(), R"JS(
+  EXPECT_EQ("300x150", EvalJs(web_contents()->GetPrimaryMainFrame(), R"JS(
     let ff = document.querySelector('fencedframe');
     `${ff.clientWidth}x${ff.clientHeight}`;
   )JS"));
@@ -131,7 +131,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kTopLevelUrl));
   RenderFrameHost* fenced_frame_root =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(),
+          web_contents()->GetPrimaryMainFrame(),
           GetTestUrl("/subresource_filter/frame_with_included_script.html"));
 
   // Ensure the disallowed script was blocked.
@@ -139,7 +139,8 @@
 
   // Ensure content settings has seen the ad as blocked (i.e. the UI was
   // shown).
-  EXPECT_TRUE(AdsBlockedInContentSettings(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      AdsBlockedInContentSettings(web_contents()->GetPrimaryMainFrame()));
   EXPECT_FALSE(AdsBlockedInContentSettings(fenced_frame_root));
 
   // Console message for subframe blocking should be displayed.
@@ -179,7 +180,7 @@
   // cancel the load.
   RenderFrameHost* fenced_frame_root =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kUrlWithIncludedScript,
+          web_contents()->GetPrimaryMainFrame(), kUrlWithIncludedScript,
           /*expected_error_code=*/net::ERR_ABORTED);
   EXPECT_FALSE(WasParsedScriptElementLoaded(fenced_frame_root));
 
@@ -237,7 +238,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kTopLevelUrl));
   RenderFrameHost* fenced_frame_root =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kFencedFrameUrl);
+          web_contents()->GetPrimaryMainFrame(), kFencedFrameUrl);
   RenderFrameHost* subframe = content::FrameMatchingPredicate(
       fenced_frame_root->GetPage(),
       base::BindRepeating(&content::FrameMatchesName, "subframe"));
diff --git a/chrome/browser/subresource_filter/subresource_filter_intercepting_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_intercepting_browsertest.cc
index 3255b1f..1681d260 100644
--- a/chrome/browser/subresource_filter/subresource_filter_intercepting_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_intercepting_browsertest.cc
@@ -149,7 +149,8 @@
         web_contents());
     enforce_console_observer.SetPattern(kActivationConsoleMessage);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), enforce_url));
-    EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_FALSE(
+        WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
     EXPECT_EQ(kActivationConsoleMessage,
               enforce_console_observer.GetMessageAt(0u));
   }
@@ -159,7 +160,8 @@
     warn_console_observer.SetPattern(kActivationWarningConsoleMessage);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), warn_url));
     warn_console_observer.Wait();
-    EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_TRUE(
+        WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
     EXPECT_EQ(kActivationWarningConsoleMessage,
               warn_console_observer.GetMessageAt(0u));
   }
@@ -199,7 +201,8 @@
   GURL url = InitializeSafeBrowsingForOutOfOrderResponses("a.com", redirect_url,
                                                           base::Seconds(0));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 }  // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
index 1cfd44cf..359d309 100644
--- a/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
@@ -130,7 +130,7 @@
   EXPECT_EQ(true, content::EvalJs(web_contents, "openWindow()",
                                   content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
   EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                   web_contents->GetMainFrame())
+                   web_contents->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Navigate again to trigger histogram logging. Make sure the navigation
@@ -177,7 +177,7 @@
   tester.ExpectTotalCount(kSubresourceFilterActionsHistogram, 0);
   // Make sure the popup UI was shown.
   EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
-                  web_contents->GetMainFrame())
+                  web_contents->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Block again.
@@ -193,7 +193,7 @@
                                   content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
   // Popup UI should not be shown.
   EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                   web_contents->GetMainFrame())
+                   web_contents->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
@@ -325,7 +325,7 @@
   tester.ExpectTotalCount(kSubresourceFilterActionsHistogram, 0);
 
   EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
-                  web_contents->GetMainFrame())
+                  web_contents->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::POPUPS));
   const bool enable_adblock_on_abusive_sites = GetParam();
   EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());
@@ -341,7 +341,7 @@
 
   // Popup UI should not be shown.
   EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                   web_contents->GetMainFrame())
+                   web_contents->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
   EXPECT_FALSE(AreDisallowedRequestsBlocked());
 }
@@ -361,7 +361,7 @@
   EXPECT_EQ(true, content::EvalJs(web_contents, "openWindow()",
                                   content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
   EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
-                  web_contents->GetMainFrame())
+                  web_contents->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::POPUPS));
   const bool enable_adblock_on_abusive_sites = GetParam();
   EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());
@@ -385,7 +385,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                   web_contents->GetMainFrame())
+                   web_contents->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
   const bool enable_adblock_on_abusive_sites = GetParam();
   EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());
diff --git a/chrome/browser/subresource_filter/subresource_filter_prerender_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_prerender_browsertest.cc
index db1cd679..71128c8 100644
--- a/chrome/browser/subresource_filter/subresource_filter_prerender_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_prerender_browsertest.cc
@@ -141,7 +141,8 @@
 
   // Now dynamically try to load `included_script.js` in the primary frame.
   // Ensure it is not filtered.
-  EXPECT_TRUE(IsDynamicScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      IsDynamicScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 // Test that we don't start filtering an unactivated prerendering page when the
@@ -237,7 +238,8 @@
 
     // But ensure we haven't shown the notification UI yet since the page is
     // still prerendering.
-    EXPECT_FALSE(AdsBlockedInContentSettings(web_contents()->GetMainFrame()));
+    EXPECT_FALSE(
+        AdsBlockedInContentSettings(web_contents()->GetPrimaryMainFrame()));
     EXPECT_FALSE(AdsBlockedInContentSettings(prerender_rfh));
   }
 
@@ -248,7 +250,7 @@
     EXPECT_CALL(observer, OnPageActivationComputed(_, _)).Times(0);
     prerender_helper_.NavigatePrimaryPage(kPrerenderingUrl);
 
-    ASSERT_EQ(web_contents()->GetMainFrame(), prerender_rfh);
+    ASSERT_EQ(web_contents()->GetPrimaryMainFrame(), prerender_rfh);
     EXPECT_TRUE(AdsBlockedInContentSettings(prerender_rfh));
   }
 }
@@ -364,7 +366,8 @@
   // filtered.
   {
     prerender_helper_.NavigatePrimaryPage(kPrerenderingUrl);
-    EXPECT_FALSE(IsDynamicScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_FALSE(
+        IsDynamicScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   }
 }
 
@@ -413,7 +416,8 @@
   {
     prerender_helper_.NavigatePrimaryPage(kPrerenderingUrl);
     ASSERT_EQ(kPrerenderingUrl, web_contents()->GetLastCommittedURL());
-    EXPECT_TRUE(IsDynamicScriptElementLoaded(web_contents()->GetMainFrame()));
+    EXPECT_TRUE(
+        IsDynamicScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
   }
 }
 
diff --git a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
index b9beccdd..7afc369 100644
--- a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
@@ -64,7 +64,8 @@
   ConfigureAsPhishingURL(url);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kActivationConsoleMessage);
@@ -76,7 +77,8 @@
       url, url, ContentSettingsType::ADS, CONTENT_SETTING_ALLOW);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // No message for allowlisted url.
   EXPECT_TRUE(console_observer.messages().empty());
@@ -90,7 +92,8 @@
   ConfigureAsPhishingURL(url);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kActivationConsoleMessage);
@@ -102,7 +105,8 @@
                                          CONTENT_SETTING_ALLOW);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // No message for loads that are not activated.
   EXPECT_TRUE(console_observer.messages().empty());
@@ -116,7 +120,8 @@
   ConfigureAsPhishingURL(url);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kActivationConsoleMessage);
@@ -130,7 +135,8 @@
   UpdatePolicy(policy);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // No message for allowlisted url.
   EXPECT_TRUE(console_observer.messages().empty());
@@ -144,7 +150,8 @@
   UpdatePolicy(policy);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest,
@@ -156,7 +163,8 @@
   // Do not configure as phishing URL.
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // Simulate allowing the subresource filter via content settings.
   HostContentSettingsMap* settings_map =
@@ -166,7 +174,8 @@
 
   // Setting the site to "allow" should not activate filtering.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest,
@@ -177,7 +186,8 @@
   ConfigureAsPhishingURL(url);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // Allowlist via a reload.
   content::TestNavigationObserver navigation_observer(web_contents(), 1);
@@ -186,7 +196,8 @@
       ->OnReloadRequested();
   navigation_observer.Wait();
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest,
@@ -197,7 +208,8 @@
   ConfigureAsPhishingURL(url);
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // Allowlist via a reload.
   content::TestNavigationObserver navigation_observer(web_contents(), 1);
@@ -206,20 +218,23 @@
       ->OnReloadRequested();
   navigation_observer.Wait();
 
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // Another navigation to the same domain should be allowlisted too.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(),
       GetTestUrl("subresource_filter/frame_with_included_script.html?query")));
-  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   // A cross site blocklisted navigation should stay activated, however.
   GURL a_url(embedded_test_server()->GetURL(
       "a.com", "/subresource_filter/frame_with_included_script.html"));
   ConfigureAsPhishingURL(a_url);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 }
 
 // Test the "smart" UI, aka the logic to hide the UI on subsequent same-domain
@@ -246,7 +261,8 @@
 
   // First load should trigger the UI.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
@@ -257,7 +273,8 @@
 
   // Second load should not trigger the UI, but should still filter content.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
@@ -270,7 +287,8 @@
 
   // Load to another domain should trigger the UI.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), b_url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
@@ -283,7 +301,8 @@
       subresource_filter::SubresourceFilterContentSettingsManager::
           kDelayBeforeShowingInfobarAgain);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
-  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(
+      WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
 
   histogram_tester.ExpectBucketCount(
       kSubresourceFilterActionsHistogram,
diff --git a/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
index f198dde..56a3f704 100644
--- a/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
@@ -69,7 +69,7 @@
   // target of the navigation.
   content::TestNavigationObserver navigation_observer(web_contents(), 1);
   EXPECT_TRUE(content::ExecJs(
-      web_contents()->GetMainFrame(),
+      web_contents()->GetPrimaryMainFrame(),
       base::StringPrintf(
           "var data_url = 'data:text/html,<script src=\"%s\"></script>';"
           "window.frames[0][0].location.href = data_url;",
diff --git a/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc
index dfc55895..2bd3cc1 100644
--- a/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc
@@ -72,7 +72,7 @@
   }
 
   void ClearTitle() {
-    ASSERT_TRUE(content::ExecJs(web_contents()->GetMainFrame(),
+    ASSERT_TRUE(content::ExecJs(web_contents()->GetPrimaryMainFrame(),
                                 "document.title = \"\";"));
   }
 };
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc
index 91737a8..d53a49de 100644
--- a/chrome/browser/supervised_user/supervised_user_interstitial.cc
+++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -158,7 +158,7 @@
       base::WrapUnique(new SupervisedUserInterstitial(
           web_contents, url, reason, frame_id, interstitial_navigation_id));
 
-  if (web_contents->GetMainFrame()->GetFrameTreeNodeId() == frame_id)
+  if (web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId() == frame_id)
     CleanUpInfoBar(web_contents);
 
   // Caller is responsible for deleting the interstitial.
@@ -213,7 +213,8 @@
 
 void SupervisedUserInterstitial::GoBack() {
   // GoBack only for main frame.
-  DCHECK_EQ(web_contents()->GetMainFrame()->GetFrameTreeNodeId(), frame_id());
+  DCHECK_EQ(web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
+            frame_id());
 
   UMA_HISTOGRAM_ENUMERATION("ManagedMode.BlockingInterstitialCommand", BACK,
                             HISTOGRAM_BOUNDING_VALUE);
@@ -227,7 +228,7 @@
                             ACCESS_REQUEST, HISTOGRAM_BOUNDING_VALUE);
 
   RequestPermissionSource source;
-  if (web_contents()->GetMainFrame()->GetFrameTreeNodeId() == frame_id())
+  if (web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId() == frame_id())
     source = RequestPermissionSource::MAIN_FRAME;
   else
     source = RequestPermissionSource::SUB_FRAME;
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
index 7d1e1b4..ef510ca 100644
--- a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
+++ b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
@@ -115,7 +115,7 @@
   // have been filtered by the NavigationThrottle.
   if (navigation_handle->IsSameDocument() &&
       navigation_handle->IsInPrimaryMainFrame()) {
-    auto* render_frame_host = web_contents()->GetMainFrame();
+    auto* render_frame_host = web_contents()->GetPrimaryMainFrame();
     int process_id = render_frame_host->GetProcess()->GetID();
     int routing_id = render_frame_host->GetRoutingID();
     bool skip_manual_parent_filter =
@@ -156,7 +156,7 @@
 }
 
 void SupervisedUserNavigationObserver::OnURLFilterChanged() {
-  auto* main_frame = web_contents()->GetMainFrame();
+  auto* main_frame = web_contents()->GetPrimaryMainFrame();
   int main_frame_process_id = main_frame->GetProcess()->GetID();
   int routing_id = main_frame->GetRoutingID();
   bool skip_manual_parent_filter =
@@ -275,7 +275,7 @@
 
   bool already_requested = base::Contains(requested_hosts_, url.host());
   bool is_main_frame =
-      frame_id == web_contents()->GetMainFrame()->GetFrameTreeNodeId();
+      frame_id == web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId();
 
   callback.Run(SupervisedUserNavigationThrottle::CallbackActions::
                    kCancelWithInterstitial,
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc b/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc
index 55929576..8d4b5bdf 100644
--- a/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc
@@ -808,7 +808,8 @@
                              kExampleHost));
 
   NavigationFinishedWaiter waiter(
-      active_contents, active_contents->GetMainFrame()->GetFrameTreeNodeId(),
+      active_contents,
+      active_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
       blocked_url);
   permission_creator()->HandleDelayedRequests();
   waiter.Wait();
@@ -932,7 +933,8 @@
                              kExampleHost));
 
   NavigationFinishedWaiter waiter(
-      active_contents, active_contents->GetMainFrame()->GetFrameTreeNodeId(),
+      active_contents,
+      active_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
       blocked_url);
   permission_creator()->HandleDelayedRequests();
   waiter.Wait();
@@ -1070,7 +1072,7 @@
       kExampleHost, "/supervised_user/fenced_frame.html");
   content::RenderFrameHost* rfh_same_origin =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kSameOriginFencedFrameUrl);
+          web_contents()->GetPrimaryMainFrame(), kSameOriginFencedFrameUrl);
   EXPECT_TRUE(rfh_same_origin);
 
   // Host1 is not blocked, and therefore must be allowed.
@@ -1078,7 +1080,7 @@
       kIframeHost1, "/supervised_user/fenced_frame.html");
   content::RenderFrameHost* rfh_host1 =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kHost1FencedFrameUrl);
+          web_contents()->GetPrimaryMainFrame(), kHost1FencedFrameUrl);
   EXPECT_TRUE(rfh_host1);
 
   // Host2 is blocked, and therefore should result in a interstitial being
@@ -1087,7 +1089,7 @@
       kIframeHost2, "/supervised_user/fenced_frame.html");
   content::RenderFrameHost* rfh_host2 =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), kHost2FencedFrameUrl,
+          web_contents()->GetPrimaryMainFrame(), kHost2FencedFrameUrl,
           net::Error::ERR_FAILED);
   EXPECT_TRUE(rfh_host2);
 }
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
index 57ff0b8..9e4eca6 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
@@ -78,14 +78,14 @@
   }
 
   void SendAccessRequest(WebContents* tab) {
-    tab->GetMainFrame()->ExecuteJavaScriptForTests(
+    tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"supervisedUserErrorPageController.requestPermission()",
         base::NullCallback());
     return;
   }
 
   void GoBack(WebContents* tab) {
-    tab->GetMainFrame()->ExecuteJavaScriptForTests(
+    tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"supervisedUserErrorPageController.goBack()", base::NullCallback());
     return;
   }
diff --git a/chrome/browser/sync/sync_encryption_keys_tab_helper_browsertest.cc b/chrome/browser/sync/sync_encryption_keys_tab_helper_browsertest.cc
index 21fda8f..840fd9d 100644
--- a/chrome/browser/sync/sync_encryption_keys_tab_helper_browsertest.cc
+++ b/chrome/browser/sync/sync_encryption_keys_tab_helper_browsertest.cc
@@ -150,7 +150,7 @@
       https_server()->GetURL("accounts.google.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
   // EncryptionKeysApi is created for the primary page as the origin is allowed.
-  EXPECT_TRUE(HasEncryptionKeysApi(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(HasEncryptionKeysApi(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kConsoleSuccessMessage);
@@ -158,7 +158,7 @@
   // Calling setSyncEncryptionKeys() in the main frame works and it gets
   // the callback by setSyncEncryptionKeys().
   const std::vector<uint8_t> kExpectedEncryptionKey = {7};
-  ExecJsSetSyncEncryptionKeys(web_contents()->GetMainFrame(),
+  ExecJsSetSyncEncryptionKeys(web_contents()->GetPrimaryMainFrame(),
                               kExpectedEncryptionKey);
   console_observer.Wait();
   EXPECT_EQ(1u, console_observer.messages().size());
@@ -180,7 +180,7 @@
       https_server()->GetURL("accounts.google.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), signin_url));
   // EncryptionKeysApi is created for the primary page.
-  EXPECT_TRUE(HasEncryptionKeysApi(web_contents()->GetMainFrame()));
+  EXPECT_TRUE(HasEncryptionKeysApi(web_contents()->GetPrimaryMainFrame()));
 
   const GURL prerendering_url =
       https_server()->GetURL("accounts.google.com", "/simple.html");
@@ -216,7 +216,7 @@
   prerender_helper().NavigatePrimaryPage(prerendering_url);
   // Ensure that loading `prerendering_url` is not activated from prerendering.
   EXPECT_FALSE(host_observer.was_activated());
-  auto* primary_main_frame = web_contents()->GetMainFrame();
+  auto* primary_main_frame = web_contents()->GetPrimaryMainFrame();
   // Ensure that the main frame has EncryptionKeysApi.
   EXPECT_TRUE(HasEncryptionKeysApi(primary_main_frame));
 
@@ -246,12 +246,12 @@
       https_server()->GetURL("accounts.google.com", "/title1.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
   // EncryptionKeysApi is created for the primary page as the origin is allowed.
-  ASSERT_TRUE(HasEncryptionKeysApi(web_contents()->GetMainFrame()));
+  ASSERT_TRUE(HasEncryptionKeysApi(web_contents()->GetPrimaryMainFrame()));
 
   const GURL main_url = https_server()->GetURL("accounts.google.com",
                                                "/fenced_frames/title1.html");
   auto* fenced_frame_host = fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(), main_url);
+      web_contents()->GetPrimaryMainFrame(), main_url);
   // EncryptionKeysApi is also created for a fenced frame since it's a main
   // frame as well.
   EXPECT_TRUE(HasEncryptionKeysApi(fenced_frame_host));
@@ -300,7 +300,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
   // EncryptionKeysApi is NOT created for the primary page as the origin is
   // disallowed.
-  EXPECT_FALSE(HasEncryptionKeysApi(web_contents()->GetMainFrame()));
+  EXPECT_FALSE(HasEncryptionKeysApi(web_contents()->GetPrimaryMainFrame()));
 
   content::WebContentsConsoleObserver console_observer(web_contents());
   console_observer.SetPattern(kConsoleFailureMessage);
@@ -308,7 +308,8 @@
   // Calling setSyncEncryptionKeys() should fail because the API is not even
   // defined.
   const std::vector<uint8_t> kEncryptionKey = {7};
-  ExecJsSetSyncEncryptionKeys(web_contents()->GetMainFrame(), kEncryptionKey);
+  ExecJsSetSyncEncryptionKeys(web_contents()->GetPrimaryMainFrame(),
+                              kEncryptionKey);
   console_observer.Wait();
   EXPECT_EQ(1u, console_observer.messages().size());
 }
diff --git a/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc b/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
index 7e32e47..a5bd0df3 100644
--- a/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
+++ b/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
@@ -177,7 +177,7 @@
   // Activate the prerendered page.
   auto* activated_rfh =
       content::NavigationSimulator::NavigateAndCommitFromDocument(
-          kPrerenderingUrl, web_contents()->GetMainFrame());
+          kPrerenderingUrl, web_contents()->GetPrimaryMainFrame());
   host_observer.WaitForActivation();
   EXPECT_TRUE(host_observer.was_activated());
   // The EncryptionKeys exists for the activated page.
@@ -194,7 +194,7 @@
 
   // Load a page that doesn't allow EncryptionKeys.
   auto* rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(
-      kCrossOriginPrerenderingUrl, web_contents()->GetMainFrame());
+      kCrossOriginPrerenderingUrl, web_contents()->GetPrimaryMainFrame());
   EXPECT_FALSE(HasEncryptionKeysApi(rfh));
   EXPECT_FALSE(HasEncryptionKeysApiInMainFrame());
 }
diff --git a/chrome/browser/sync/test/integration/sessions_helper.cc b/chrome/browser/sync/test/integration/sessions_helper.cc
index 8a18e5b..d4b74b2 100644
--- a/chrome/browser/sync/test/integration/sessions_helper.cc
+++ b/chrome/browser/sync/test/integration/sessions_helper.cc
@@ -141,9 +141,9 @@
                                          ui::PAGE_TRANSITION_LINK, false,
                                          false);
   open_url_params.source_render_frame_id =
-      source_contents->GetMainFrame()->GetRoutingID();
+      source_contents->GetPrimaryMainFrame()->GetRoutingID();
   open_url_params.source_render_process_id =
-      source_contents->GetMainFrame()->GetProcess()->GetID();
+      source_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
 
   content::WebContents* new_contents =
       source_contents->OpenURL(open_url_params);
diff --git a/chrome/browser/tab_contents/form_interaction_tab_helper_unittest.cc b/chrome/browser/tab_contents/form_interaction_tab_helper_unittest.cc
index 39f5a02..e9499a7 100644
--- a/chrome/browser/tab_contents/form_interaction_tab_helper_unittest.cc
+++ b/chrome/browser/tab_contents/form_interaction_tab_helper_unittest.cc
@@ -111,7 +111,7 @@
   EXPECT_FALSE(helper->had_form_interaction());
 
   auto* parent_tester =
-      content::RenderFrameHostTester::For(contents->GetMainFrame());
+      content::RenderFrameHostTester::For(contents->GetPrimaryMainFrame());
   auto* child = content::NavigationSimulator::NavigateAndCommitFromDocument(
       GURL("https://foochild.com"), parent_tester->AppendChild("child"));
 
diff --git a/chrome/browser/tab_contents/view_source_browsertest.cc b/chrome/browser/tab_contents/view_source_browsertest.cc
index b765a852..480a20d 100644
--- a/chrome/browser/tab_contents/view_source_browsertest.cc
+++ b/chrome/browser/tab_contents/view_source_browsertest.cc
@@ -255,7 +255,7 @@
   content::WebContents* original_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* original_main_frame =
-      original_contents->GetMainFrame();
+      original_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* original_child_frame =
       ChildFrameAt(original_main_frame, 0);
   ASSERT_TRUE(original_child_frame);
@@ -282,7 +282,7 @@
   content::WebContents* view_source_contents =
       view_source_contents_observer.GetWebContents();
   content::RenderFrameHost* view_source_frame =
-      view_source_contents->GetMainFrame();
+      view_source_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(WaitForLoadStop(view_source_contents));
 
   // Verify that the last committed URL is the same in the original and the
@@ -336,7 +336,7 @@
   content::WebContents* original_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* original_main_frame =
-      original_contents->GetMainFrame();
+      original_contents->GetPrimaryMainFrame();
 
   // Submit the form and verify that we arrived at the expected location.
   content::TestNavigationObserver form_post_observer(original_contents, 1);
@@ -346,7 +346,7 @@
   GURL target_url(embedded_test_server()->GetURL("a.com", "/echoall"));
 
   content::RenderFrameHost* current_main_frame =
-      original_contents->GetMainFrame();
+      original_contents->GetPrimaryMainFrame();
   if (content::CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()) {
     // When ProactivelySwapBrowsingInstance or RenderDocument is enabled on
     // same-site main frame navigations, the form submission above will result
@@ -407,7 +407,7 @@
   // Verify that the original contents and the view-source contents are in a
   // different process - see https://crbug.com/699493.
   EXPECT_NE(current_main_frame->GetSiteInstance(),
-            view_source_contents->GetMainFrame()->GetSiteInstance());
+            view_source_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Verify the title of view-source is derived from the URL (not from the title
   // of the original contents).
@@ -455,7 +455,7 @@
   EXPECT_EQ(GURL(), browser()
                         ->tab_strip_model()
                         ->GetActiveWebContents()
-                        ->GetMainFrame()
+                        ->GetPrimaryMainFrame()
                         ->GetLastCommittedURL());
 
   // Open a view source tab, and watch for its main network request.
@@ -464,7 +464,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ViewSource();
   content::WebContents* view_source_contents =
       view_source_contents_observer.GetWebContents();
@@ -580,9 +580,9 @@
 
   // Verify that view-source opens in a new process - https://crbug.com/699493.
   EXPECT_NE(original_child_frame->GetSiteInstance(),
-            view_source_contents->GetMainFrame()->GetSiteInstance());
+            view_source_contents->GetPrimaryMainFrame()->GetSiteInstance());
   EXPECT_NE(original_contents->GetSiteInstance(),
-            view_source_contents->GetMainFrame()->GetSiteInstance());
+            view_source_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Verify the title is derived from the URL.
   GURL original_url = original_child_frame->GetLastCommittedURL();
@@ -635,7 +635,7 @@
         "document.body.appendChild(frame);",
         subframe_url.c_str());
     content::TestNavigationObserver navigation_observer(original_contents);
-    original_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+    original_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         base::ASCIIToUTF16(create_frame_script), base::NullCallback());
     navigation_observer.Wait();
   }
diff --git a/chrome/browser/task_manager/providers/web_contents/portal_task.cc b/chrome/browser/task_manager/providers/web_contents/portal_task.cc
index 285081bc..5e00edc 100644
--- a/chrome/browser/task_manager/providers/web_contents/portal_task.cc
+++ b/chrome/browser/task_manager/providers/web_contents/portal_task.cc
@@ -23,7 +23,7 @@
 
   // Imitate the UI style of Subframe task.
   content::SiteInstance* site_instance =
-      web_contents->GetMainFrame()->GetSiteInstance();
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   std::u16string site_url =
       base::UTF8ToUTF16(site_instance->GetSiteURL().spec());
   int message_id = site_instance->GetBrowserContext()->IsOffTheRecord()
@@ -64,7 +64,8 @@
       web_contents()->GetResponsibleWebContents();
   if (responsible_contents == web_contents())
     return nullptr;
-  return task_provider_->GetTaskOfFrame(responsible_contents->GetMainFrame());
+  return task_provider_->GetTaskOfFrame(
+      responsible_contents->GetPrimaryMainFrame());
 }
 
 }  // namespace task_manager
diff --git a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc
index b461821..f21c405 100644
--- a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc
+++ b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc
@@ -60,7 +60,7 @@
     : RendererTask(title,
                    icon,
                    web_contents,
-                   web_contents->GetMainFrame()->GetProcess()) {}
+                   web_contents->GetPrimaryMainFrame()->GetProcess()) {}
 
 RendererTask::RendererTask(const std::u16string& title,
                            const gfx::ImageSkia* icon,
diff --git a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
index eea1a8c..8e9521a5 100644
--- a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
@@ -383,7 +383,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title2.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          GetWebContents()->GetMainFrame(), kFencedFrameUrl);
+          GetWebContents()->GetPrimaryMainFrame(), kFencedFrameUrl);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   // The navigation in the fenced frame should not change the title of the
diff --git a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
index fd80a29c..3a3d7a2 100644
--- a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
+++ b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
@@ -121,7 +121,7 @@
 }
 
 void WebContentsTaskProvider::WebContentsEntry::CreateAllTasks() {
-  DCHECK(web_contents()->GetMainFrame());
+  DCHECK(web_contents()->GetPrimaryMainFrame());
   web_contents()->ForEachFrame(base::BindRepeating(
       &WebContentsEntry::CreateTaskForFrame, base::Unretained(this)));
 }
@@ -257,7 +257,7 @@
     return;
 
   RendererTask* main_frame_task =
-      GetTaskForFrame(web_contents()->GetMainFrame());
+      GetTaskForFrame(web_contents()->GetPrimaryMainFrame());
   if (!main_frame_task)
     return;
 
@@ -311,7 +311,7 @@
 
   bool site_instance_exists = site_instance_infos_.count(site_instance) != 0;
   bool is_primary_main_frame =
-      (render_frame_host == web_contents()->GetMainFrame());
+      (render_frame_host == web_contents()->GetPrimaryMainFrame());
   bool site_instance_is_main = (site_instance == main_frame_site_instance_);
 
   std::unique_ptr<RendererTask> new_task;
@@ -335,7 +335,8 @@
       main_frame_site_instance_ = site_instance;
     } else {
       new_task = std::make_unique<SubframeTask>(
-          render_frame_host, GetTaskForFrame(web_contents()->GetMainFrame()));
+          render_frame_host,
+          GetTaskForFrame(web_contents()->GetPrimaryMainFrame()));
     }
   }
 
diff --git a/chrome/browser/task_manager/providers/worker_task_provider_browsertest.cc b/chrome/browser/task_manager/providers/worker_task_provider_browsertest.cc
index ea7850c..75339f57 100644
--- a/chrome/browser/task_manager/providers/worker_task_provider_browsertest.cc
+++ b/chrome/browser/task_manager/providers/worker_task_provider_browsertest.cc
@@ -59,7 +59,7 @@
 int GetChildProcessID(Browser* browser) {
   return browser->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->GetProcess()
       ->GetID();
 }
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl.cc b/chrome/browser/task_manager/sampling/task_manager_impl.cc
index fbd69e4..0f336e3 100644
--- a/chrome/browser/task_manager/sampling/task_manager_impl.cc
+++ b/chrome/browser/task_manager/sampling/task_manager_impl.cc
@@ -467,7 +467,7 @@
     content::WebContents* web_contents) const {
   if (!web_contents)
     return -1;
-  content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
   Task* task = GetTaskByRoute(rfh->GetGlobalId());
   if (!task)
     return -1;
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index 4373817..cb8c7c0b 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -289,7 +289,7 @@
   content::WebContentsAddedObserver web_contents_added_observer;
   int dummy_value = 0;
   ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
-      tab1->GetMainFrame(),
+      tab1->GetPrimaryMainFrame(),
       "window.open('title3.html', '_blank');\n"
       "window.domAutomationController.send(55);\n"
       "while(1);",
@@ -301,8 +301,8 @@
   // Make sure the new WebContents is in tab1's hung renderer process.
   ASSERT_NE(nullptr, tab2);
   ASSERT_NE(tab1, tab2);
-  ASSERT_EQ(tab1->GetMainFrame()->GetProcess(),
-            tab2->GetMainFrame()->GetProcess())
+  ASSERT_EQ(tab1->GetPrimaryMainFrame()->GetProcess(),
+            tab2->GetPrimaryMainFrame()->GetProcess())
       << "New WebContents must be in the same process as the old WebContents, "
       << "so that the new tab doesn't finish loading (what this test is all "
       << "about)";
@@ -688,7 +688,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js),
                                   base::NullCallback());
   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
@@ -728,7 +728,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js),
                                   base::NullCallback());
 
@@ -744,7 +744,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js),
                                   base::NullCallback());
   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
@@ -912,7 +912,8 @@
 
   // Simulate a user gesture on the frame about to be navigated so that the
   // corresponding navigation entry is not marked as skippable.
-  content::RenderFrameHost* child_frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child_frame =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   content::RenderFrameHost* grandchild_frame = ChildFrameAt(child_frame, 0);
   grandchild_frame->ExecuteJavaScriptWithUserGestureForTests(
       u"a=5", base::NullCallback());
@@ -920,7 +921,7 @@
   GURL d_url = embedded_test_server()->GetURL(
       "d.com", "/cross_site_iframe_factory.html?d(e)");
   ASSERT_TRUE(content::ExecuteScript(
-      tab->GetMainFrame(),
+      tab->GetPrimaryMainFrame(),
       "frames[0][0].location.href = '" + d_url.spec() + "';"));
 
   ASSERT_NO_FATAL_FAILURE(
@@ -1051,7 +1052,10 @@
   // Reload the subframe and verify it has re-appeared in the task manager.
   // This is a regression test for https://crbug.com/642958.
   ASSERT_TRUE(content::ExecuteScript(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+      browser()
+          ->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame(),
       "document.getElementById('frame1').src = '" + b_url.spec() + "';"));
 
   // Verify the expected number of b.com and c.com subframes.
@@ -1194,9 +1198,11 @@
   const std::string r_script =
       R"( document.getElementById('frame1').src='/title1.html';
           document.title='aac'; )";
-  ASSERT_TRUE(content::ExecuteScript(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      r_script));
+  ASSERT_TRUE(content::ExecuteScript(browser()
+                                         ->tab_strip_model()
+                                         ->GetActiveWebContents()
+                                         ->GetPrimaryMainFrame(),
+                                     r_script));
   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("aac")));
   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
   if (!ShouldExpectSubframes()) {
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 e261e9a..34cefa2c 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
@@ -112,7 +112,7 @@
     : password_client_(password_client),
       authenticator_(std::move(authenticator)),
       source_id_(password_client->web_contents()
-                     ->GetMainFrame()
+                     ->GetPrimaryMainFrame()
                      ->GetPageUkmSourceId()) {}
 
 TouchToFillController::~TouchToFillController() {
diff --git a/chrome/browser/translate/translate_frame_binder_browsertest.cc b/chrome/browser/translate/translate_frame_binder_browsertest.cc
index 2d48f5b..3ef4b69 100644
--- a/chrome/browser/translate/translate_frame_binder_browsertest.cc
+++ b/chrome/browser/translate/translate_frame_binder_browsertest.cc
@@ -194,7 +194,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   base::RunLoop run_loop;
   if (test_browser_client.WaitForBinding(fenced_frame_host,
                                          run_loop.QuitClosure())) {
diff --git a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
index c87929c..d5c9044 100644
--- a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
+++ b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
@@ -358,7 +358,7 @@
     params.writing_direction_right_to_left = 0;
 #endif  // BUILDFLAG(IS_MAC)
     params.edit_flags = blink::ContextMenuDataEditFlags::kCanTranslate;
-    return new TestRenderViewContextMenu(*web_contents()->GetMainFrame(),
+    return new TestRenderViewContextMenu(*web_contents()->GetPrimaryMainFrame(),
                                          params);
   }
 
@@ -877,7 +877,7 @@
       url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
   int pending_id =
       web_contents()->GetController().GetPendingEntry()->GetUniqueID();
-  content::RenderFrameHostTester::For(web_contents()->GetMainFrame())
+  content::RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
       ->SendNavigateWithTransition(pending_id, false, url,
                                    ui::PAGE_TRANSITION_TYPED);
 
diff --git a/chrome/browser/ui/android/passwords/manual_filling_view_android.cc b/chrome/browser/ui/android/passwords/manual_filling_view_android.cc
index ceb51cb8..87987da 100644
--- a/chrome/browser/ui/android/passwords/manual_filling_view_android.cc
+++ b/chrome/browser/ui/android/passwords/manual_filling_view_android.cc
@@ -261,7 +261,8 @@
   content::WebContents* web_contents =
       content::WebContents::FromJavaWebContents(j_web_contents);
 
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   std::vector<std::string> usernames;
   std::vector<std::string> passwords;
   base::android::AppendJavaStringArrayToStringVector(env, j_usernames,
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 2165554..232fcdc 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3937,9 +3937,6 @@
       <message name="IDS_CONTEXTUAL_SEARCH_QUICK_ACTION_CAPTION_GENERIC_WEBSITE" desc="Caption displayed in the Contextual Search bar prompting the user to navigate to a web page.">
         Go to page
       </message>
-      <message name="IDS_CONTEXTUAL_SEARCH_IPH_TAP" desc="An in-product-help message for encouraging users to tap instead of long pressing to trigger the Tap to Search feature.">
-        You can also search with a quick tap on a word
-      </message>
 
       <!-- Web apps -->
       <message name="IDS_WEBAPP_ACTIVITY_TITLE" desc="Title in recent tasks list for web apps, i.e. web pages that are shown in a separate window">
diff --git a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc
index 0f1f2ba..cbf4ee9f 100644
--- a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc
+++ b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc
@@ -146,7 +146,7 @@
 
   // Activate the prerendered page.
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      prerendering_url, GetActiveWebContents()->GetMainFrame());
+      prerendering_url, GetActiveWebContents()->GetPrimaryMainFrame());
   EXPECT_EQ(prerender_frame->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kActive);
 
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc
index 3217ce1..0dee4ec 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -337,7 +337,7 @@
   if (!blocked)
     web_contents->Focus();
   // RenderFrameHost may be NULL during shutdown.
-  content::RenderFrameHost* host = web_contents->GetMainFrame();
+  content::RenderFrameHost* host = web_contents->GetPrimaryMainFrame();
   if (host && host->IsRenderFrameLive()) {
     mojo::Remote<extensions::mojom::AppWindow> app_window;
     host->GetRemoteInterfaces()->GetInterface(
diff --git a/chrome/browser/ui/ash/ambient/DIR_METADATA b/chrome/browser/ui/ash/ambient/DIR_METADATA
index 5cf9e51..e8a674f9 100644
--- a/chrome/browser/ui/ash/ambient/DIR_METADATA
+++ b/chrome/browser/ui/ash/ambient/DIR_METADATA
@@ -1,3 +1 @@
-monorail {
-  component: "UI>Shell>Assistant"
-}
+mixins: "//ash/ambient/COMMON_METADATA"
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
index caa6c2d..1318d5e 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
@@ -162,7 +162,7 @@
 
   // Set the background to be transparent for custom keyboard window shape.
   content::RenderWidgetHostView* view =
-      web_contents_->GetMainFrame()->GetView();
+      web_contents_->GetPrimaryMainFrame()->GetView();
   view->SetBackgroundColor(SK_ColorTRANSPARENT);
   view->GetNativeView()->SetTransparent(true);
 
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index e494283..9612edb3 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -1368,7 +1368,7 @@
     // in a random RenderFrameHost is Good Enough™.
     window_->Init(GURL(std::string()),
                   new extensions::AppWindowContentsImpl(window_),
-                  creator_web_contents_->GetMainFrame(), params);
+                  creator_web_contents_->GetPrimaryMainFrame(), params);
   }
 
   V2App(const V2App&) = delete;
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura_browsertest.cc b/chrome/browser/ui/aura/accessibility/automation_manager_aura_browsertest.cc
index 83a0b075..b870343 100644
--- a/chrome/browser/ui/aura/accessibility/automation_manager_aura_browsertest.cc
+++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura_browsertest.cc
@@ -210,7 +210,7 @@
 
   WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Click me");
 
-  auto* frame_host = web_contents->GetMainFrame();
+  auto* frame_host = web_contents->GetPrimaryMainFrame();
   ui::AXTreeID ax_tree_id = GetAXTreeIDFromRenderFrameHost(frame_host);
   ASSERT_NE(ax_tree_id, ui::AXTreeIDUnknown());
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
index 49a842cd..0bd9417 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
@@ -67,7 +67,7 @@
   }
 
   content::RenderFrameHost* main_rfh() {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   BrowserAutofillManager& autofill_manager() {
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index e44e6807..85004e5 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -263,7 +263,7 @@
     ContentAutofillDriverFactory* factory =
         ContentAutofillDriverFactory::FromWebContents(web_contents());
     ContentAutofillDriver* driver =
-        factory->DriverForFrame(web_contents()->GetMainFrame());
+        factory->DriverForFrame(web_contents()->GetPrimaryMainFrame());
     // Fake that |driver| has queried a form.
     ContentAutofillRouterTestApi(
         &ContentAutofillDriverTestApi(driver).autofill_router())
@@ -324,7 +324,7 @@
   CreateExternalDelegate() override {
     autofill_router_ = std::make_unique<ContentAutofillRouter>();
     autofill_driver_ = std::make_unique<NiceMock<MockAutofillDriver>>(
-        web_contents()->GetMainFrame(), autofill_router_.get());
+        web_contents()->GetPrimaryMainFrame(), autofill_router_.get());
     autofill_driver_->set_autofill_manager(
         std::make_unique<MockBrowserAutofillManager>(autofill_driver_.get(),
                                                      autofill_client_.get()));
@@ -625,7 +625,7 @@
   ContentAutofillDriverFactory* factory =
       ContentAutofillDriverFactory::FromWebContents(web_contents());
   ContentAutofillDriver* driver =
-      factory->DriverForFrame(web_contents()->GetMainFrame());
+      factory->DriverForFrame(web_contents()->GetPrimaryMainFrame());
   NiceMock<MockAutofillExternalDelegate> delegate(
       static_cast<BrowserAutofillManager*>(driver->autofill_manager()), driver);
 
@@ -702,7 +702,7 @@
   ContentAutofillDriverFactory* factory =
       ContentAutofillDriverFactory::FromWebContents(web_contents());
   ContentAutofillDriver* driver =
-      factory->DriverForFrame(web_contents()->GetMainFrame());
+      factory->DriverForFrame(web_contents()->GetPrimaryMainFrame());
   StrictMock<MockAutofillExternalDelegate> delegate(
       static_cast<BrowserAutofillManager*>(driver->autofill_manager()), driver);
   StrictMock<TestAutofillPopupController>* test_controller =
@@ -733,7 +733,7 @@
   ContentAutofillDriverFactory* factory =
       ContentAutofillDriverFactory::FromWebContents(web_contents());
   ContentAutofillDriver* driver =
-      factory->DriverForFrame(web_contents()->GetMainFrame());
+      factory->DriverForFrame(web_contents()->GetPrimaryMainFrame());
   NiceMock<MockAutofillExternalDelegate> delegate(
       static_cast<BrowserAutofillManager*>(driver->autofill_manager()), driver);
   NiceMock<TestAutofillPopupController>* test_controller =
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 342a510..9debc89 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -212,7 +212,7 @@
 }
 
 ukm::SourceId ChromeAutofillClient::GetUkmSourceId() {
-  return web_contents()->GetMainFrame()->GetPageUkmSourceId();
+  return web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
 }
 
 AddressNormalizer* ChromeAutofillClient::GetAddressNormalizer() {
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc
index 6b04fe9..148b5102 100644
--- a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc
@@ -47,7 +47,7 @@
       : LocalCardMigrationBubbleControllerImpl(web_contents) {}
 
   void SimulateNavigation() {
-    content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+    content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame();
     content::MockNavigationHandle navigation_handle(GURL(), rfh);
     navigation_handle.set_has_committed(true);
     DidFinishNavigation(&navigation_handle);
diff --git a/chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc b/chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc
index 116182328..ffd6436 100644
--- a/chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc
+++ b/chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc
@@ -133,7 +133,7 @@
 
   AutofillOfferManager* GetOfferManager() {
     return ContentAutofillDriver::GetForRenderFrameHost(
-               GetWebContents()->GetMainFrame())
+               GetWebContents()->GetPrimaryMainFrame())
         ->autofill_manager()
         ->GetOfferManager();
   }
diff --git a/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc
index 369975e..a67dcb7 100644
--- a/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc
+++ b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc
@@ -56,7 +56,7 @@
   if (params_.navigated_or_inserted_contents &&
       params_.disposition == WindowOpenDisposition::NEW_POPUP) {
     content::RenderFrameHost* host =
-        params_.navigated_or_inserted_contents->GetMainFrame();
+        params_.navigated_or_inserted_contents->GetPrimaryMainFrame();
     DCHECK(host);
     mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> client;
     host->GetRemoteAssociatedInterfaces()->GetInterface(&client);
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index 4785697..21d4a9a5 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -554,14 +554,14 @@
 
   // Navigate it elsewhere.
   content::TestNavigationObserver nav_observer(popup);
-  popup->GetMainFrame()->ExecuteJavaScriptForTests(
+  popup->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"location.href = '/empty.html'", base::NullCallback());
   nav_observer.Wait();
 
   // Have it close itself.
   CloseObserver close_observer(popup);
-  popup->GetMainFrame()->ExecuteJavaScriptForTests(u"window.close()",
-                                                   base::NullCallback());
+  popup->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"window.close()",
+                                                          base::NullCallback());
   close_observer.Wait();
 }
 
@@ -650,7 +650,7 @@
 #endif
   bool ignored;
   javascript_dialogs::AppModalDialogManager::GetInstance()->RunJavaScriptDialog(
-      tab, tab->GetMainFrame(), content::JAVASCRIPT_DIALOG_TYPE_ALERT,
+      tab, tab->GetPrimaryMainFrame(), content::JAVASCRIPT_DIALOG_TYPE_ALERT,
       std::u16string(), std::u16string(), base::DoNothing(), &ignored);
   javascript_dialogs::AppModalDialogController* dialog =
       ui_test_utils::WaitForAppModalDialog();
@@ -823,8 +823,10 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(
                      "a.com", "/popup_blocker/popup-many.html")));
-  content::RenderFrameHostWrapper rfh(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+  content::RenderFrameHostWrapper rfh(browser()
+                                          ->tab_strip_model()
+                                          ->GetActiveWebContents()
+                                          ->GetPrimaryMainFrame());
   int process_id = rfh->GetProcess()->GetID();
   int frame_routing_id = rfh->GetRoutingID();
 
@@ -885,10 +887,10 @@
   EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(tab_2, ""));
 
   EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
-                   tab_1->GetMainFrame())
+                   tab_1->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
   EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
-                  tab_2->GetMainFrame())
+                  tab_2->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
@@ -898,7 +900,10 @@
   ~PopupBlockerFencedFrameTest() override = default;
 
   content::RenderFrameHost* primary_main_frame_host() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
  protected:
diff --git a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc
index 1f41e7e..ac78ea7 100644
--- a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc
@@ -71,7 +71,7 @@
 
   // Open and close two pop-ups, the opener id does not change.
   const ukm::SourceId opener_source_id =
-      GetActiveWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetActiveWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
   OpenAndClosePopup();
   OpenAndClosePopup();
 
@@ -101,7 +101,7 @@
 
   // Open and close two pop-ups, the opener id does not change.
   const ukm::SourceId opener_source_id =
-      GetActiveWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      GetActiveWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
   OpenAndClosePopup();
   OpenAndClosePopup();
 
diff --git a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
index 412b63a..c826566 100644
--- a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
@@ -301,7 +301,7 @@
   // Is blocked by the popup blocker.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
-                  web_contents->GetMainFrame())
+                  web_contents->GetPrimaryMainFrame())
                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Click through to open the popup.
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
index b29c7d34c..82eaa19 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
@@ -260,9 +260,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerDisabledTest,
@@ -280,9 +280,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   RoundTripAndVerifyLogMessages(console_observer, web_contents, {},
                                 {blocked_content::kAbusiveWarnMessage,
@@ -311,9 +311,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Since the policy change can take effect without browser restart, verify
   // that enabling the policy here should disallow opening new tabs or windows
@@ -337,9 +337,9 @@
       web_contents1, "openWindow()", &opened_window));
   EXPECT_FALSE(opened_window);
   // Make sure the popup UI was shown.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents1->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents1->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -360,9 +360,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -378,9 +378,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -399,9 +399,9 @@
                                                    &opened_window));
   EXPECT_FALSE(opened_window);
   // Make sure the popup UI was shown.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Block again.
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
@@ -415,9 +415,9 @@
                                                    &opened_window));
   EXPECT_TRUE(opened_window);
   // Popup UI should not be shown.
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -438,9 +438,9 @@
   EXPECT_FALSE(opened_window);
 
   // Make sure the popup UI was shown.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Click through.
   content::TestNavigationObserver navigation_observer(nullptr, 1);
@@ -522,9 +522,9 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()"));
 
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 
   // Navigate to |b_url|, which should successfully open the popup.
 
@@ -536,9 +536,9 @@
   navigation_observer.Wait();
 
   // Popup UI should not be shown.
-  EXPECT_FALSE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
+                   web_contents->GetPrimaryMainFrame())
+                   ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -555,9 +555,9 @@
   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                    &sent_open));
   EXPECT_TRUE(sent_open);
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
@@ -574,10 +574,10 @@
     EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
         web_contents, "openWindow()", &opened_window));
     EXPECT_EQ(expect_block, !opened_window);
-    EXPECT_EQ(
-        expect_block,
-        PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
-            ->IsContentBlocked(ContentSettingsType::POPUPS));
+    EXPECT_EQ(expect_block,
+              PageSpecificContentSettings::GetForFrame(
+                  web_contents->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
   };
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
@@ -719,8 +719,10 @@
   // Navigate to an abusive page.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
 
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   int main_frame_process_id = main_frame->GetProcess()->GetID();
   int main_frame_routing_id = main_frame->GetRoutingID();
 
@@ -746,17 +748,19 @@
   // Navigate to an abusive page.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), a_url));
 
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
 
   content::RenderFrameHost* sub_frame = content::ChildFrameAt(main_frame, 0);
   EXPECT_NE(sub_frame, nullptr);
   EXPECT_EQ(false, content::EvalJs(sub_frame, "!!window.open()"));
 
   // Popup UI should be shown.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents()->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 class SafeBrowsingTriggeredPopupBlockerPrerenderingBrowserTest
@@ -793,7 +797,7 @@
                                   {blocked_content::kAbusiveEnforceMessage});
     EXPECT_GE(console_observer.messages().size(), 1u);
     for (auto& message : console_observer.messages())
-      EXPECT_EQ(message.source_frame, web_contents()->GetMainFrame());
+      EXPECT_EQ(message.source_frame, web_contents()->GetPrimaryMainFrame());
   }
 
   // Load prerendering and ensure that the source frame for console logs in
@@ -849,13 +853,13 @@
 
   // Activate prerendering, should trigger the popup blocker.
   prerender_helper_.NavigatePrimaryPage(prerendering_url);
-  EXPECT_EQ(false,
-            content::EvalJs(web_contents()->GetMainFrame(), "openWindow()",
-                            content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
+  EXPECT_EQ(false, content::EvalJs(web_contents()->GetPrimaryMainFrame(),
+                                   "openWindow()",
+                                   content::EXECUTE_SCRIPT_USE_MANUAL_REPLY));
   // Make sure the popup UI was shown in an activated document.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents()->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
 class SafeBrowsingTriggeredPopupBlockerFencedFrameBrowserTest
@@ -894,12 +898,12 @@
 
   // Loading a fenced frame should not trigger the popup blocker.
   auto* fenced_frame_host = fenced_frame_test_helper().CreateFencedFrame(
-      first_web_contents->GetMainFrame(), fenced_url);
+      first_web_contents->GetPrimaryMainFrame(), fenced_url);
   EXPECT_EQ(false, content::EvalJs(fenced_frame_host, "!!window.open()"));
 
   // Check if the popup UI was shown from the previous web contents.
   EXPECT_FALSE(PageSpecificContentSettings::GetForFrame(
-                   first_web_contents->GetMainFrame())
+                   first_web_contents->GetPrimaryMainFrame())
                    ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
 
@@ -916,11 +920,11 @@
   // Load a fenced frame.
   GURL fenced_url(embedded_test_server()->GetURL("/fenced_frames/title1.html"));
   auto* fenced_frame_host = fenced_frame_test_helper().CreateFencedFrame(
-      web_contents()->GetMainFrame(), fenced_url);
+      web_contents()->GetPrimaryMainFrame(), fenced_url);
   EXPECT_EQ(false, content::EvalJs(fenced_frame_host, "!!window.open()"));
 
   // Popup UI should be shown.
-  EXPECT_TRUE(
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame())
-          ->IsContentBlocked(ContentSettingsType::POPUPS));
+  EXPECT_TRUE(PageSpecificContentSettings::GetForFrame(
+                  web_contents()->GetPrimaryMainFrame())
+                  ->IsContentBlocked(ContentSettingsType::POPUPS));
 }
diff --git a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
index 1dbae37..d5cf28d6 100644
--- a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
@@ -125,7 +125,7 @@
     const GURL fenced_frame_url =
         embedded_test_server()->GetURL("/fenced_frames/title1.html");
     ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-        web_contents->GetMainFrame(), fenced_frame_url));
+        web_contents->GetPrimaryMainFrame(), fenced_frame_url));
     EXPECT_EQ(web_contents->GetVisibility(), content::Visibility::HIDDEN);
   }
 
diff --git a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc
index 1424ba9..076095d 100644
--- a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc
+++ b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc
@@ -93,7 +93,7 @@
   // previous navigation commit.
   ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
   ukm::SourceId opener_source_id =
-      handle->GetWebContents()->GetMainFrame()->GetPageUkmSourceId();
+      handle->GetWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
   if (opener_source_id != ukm::kInvalidSourceId && ukm_recorder) {
     ukm::builders::AbusiveExperienceHeuristic_TabUnder(opener_source_id)
         .SetDidTabUnder(true)
@@ -194,7 +194,7 @@
     const std::string error =
         base::StringPrintf(kBlockTabUnderFormatMessage,
                            navigation_handle()->GetURL().spec().c_str());
-    contents->GetMainFrame()->AddMessageToConsole(
+    contents->GetPrimaryMainFrame()->AddMessageToConsole(
         blink::mojom::ConsoleMessageLevel::kError, error.c_str());
     LogAction(Action::kBlocked);
     ShowUI();
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index b3338d65..63d64ac 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1463,8 +1463,10 @@
   // avoid flashing white when navigating from a site with a dark background to
   // another site with a dark background.
   if (old_contents && new_contents) {
-    RenderWidgetHostView* old_view = old_contents->GetMainFrame()->GetView();
-    RenderWidgetHostView* new_view = new_contents->GetMainFrame()->GetView();
+    RenderWidgetHostView* old_view =
+        old_contents->GetPrimaryMainFrame()->GetView();
+    RenderWidgetHostView* new_view =
+        new_contents->GetPrimaryMainFrame()->GetView();
     if (old_view && new_view)
       new_view->TakeFallbackContentFrom(old_view);
   }
@@ -1711,7 +1713,7 @@
   }
 
   page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage(
-      source->GetMainFrame(), std::move(features));
+      source->GetPrimaryMainFrame(), std::move(features));
   window_->SetBounds(bounds);
 }
 
@@ -2403,11 +2405,13 @@
   // a new tab. (There is also code in RenderFrameHostManager to do something
   // similar for intra-tab navigations.)
   if (old_contents && new_contents) {
-    // While GetMainFrame() is guaranteed to return non-null, GetView() is not,
-    // e.g. between WebContents creation and creation of the
+    // While GetPrimaryMainFrame() is guaranteed to return non-null, GetView()
+    // is not, e.g. between WebContents creation and creation of the
     // RenderWidgetHostView.
-    RenderWidgetHostView* old_view = old_contents->GetMainFrame()->GetView();
-    RenderWidgetHostView* new_view = new_contents->GetMainFrame()->GetView();
+    RenderWidgetHostView* old_view =
+        old_contents->GetPrimaryMainFrame()->GetView();
+    RenderWidgetHostView* new_view =
+        new_contents->GetPrimaryMainFrame()->GetView();
     if (old_view && new_view)
       new_view->CopyBackgroundColorIfPresentFrom(*old_view);
   }
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index e643f15d..73af1a6a 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -293,7 +293,7 @@
   void NavigationEntryCommitted(
       const content::LoadCommittedDetails& details) override {
     content::RenderViewHost* rvh =
-        web_contents()->GetMainFrame()->GetRenderViewHost();
+        web_contents()->GetPrimaryMainFrame()->GetRenderViewHost();
     render_view_sizes_[rvh].rwhv_commit_size =
         web_contents()->GetRenderWidgetHostView()->GetViewBounds().size();
     render_view_sizes_[rvh].wcv_commit_size =
@@ -483,7 +483,7 @@
   {
     content::WebContentsConsoleObserver confirm_observer(second_tab);
     confirm_observer.SetPattern("*confirm*suppressed*");
-    second_tab->GetMainFrame()->ExecuteJavaScriptForTests(
+    second_tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"confirm('Activate!');", base::NullCallback());
     confirm_observer.Wait();
   }
@@ -495,7 +495,7 @@
   {
     content::WebContentsConsoleObserver prompt_observer(second_tab);
     prompt_observer.SetPattern("*prompt*suppressed*");
-    second_tab->GetMainFrame()->ExecuteJavaScriptForTests(
+    second_tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"prompt('Activate!');", base::NullCallback());
     prompt_observer.Wait();
   }
@@ -508,8 +508,8 @@
       javascript_dialogs::TabModalDialogManager::FromWebContents(second_tab);
   base::RunLoop alert_wait;
   js_dialog_manager->SetDialogShownCallbackForTesting(alert_wait.QuitClosure());
-  second_tab->GetMainFrame()->ExecuteJavaScriptForTests(u"alert('Activate!');",
-                                                        base::NullCallback());
+  second_tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+      u"alert('Activate!');", base::NullCallback());
   alert_wait.Run();
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
@@ -614,7 +614,7 @@
   // request is started.
   {
     auto script = content::JsReplace("window.location = $1;", kSecondUrl);
-    ASSERT_TRUE(content::ExecJs(contents->GetMainFrame(), script,
+    ASSERT_TRUE(content::ExecJs(contents->GetPrimaryMainFrame(), script,
                                 content::EXECUTE_SCRIPT_NO_USER_GESTURE));
     ASSERT_TRUE(manager.WaitForRequestStart());
   }
@@ -624,8 +624,8 @@
     base::RunLoop run_loop;
 
     js_dialog_manager->SetDialogShownCallbackForTesting(run_loop.QuitClosure());
-    contents->GetMainFrame()->ExecuteJavaScriptForTests(u"alert('one'); ",
-                                                        base::NullCallback());
+    contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+        u"alert('one'); ", base::NullCallback());
     run_loop.Run();
 
     ASSERT_TRUE(js_dialog_manager->IsShowingDialogForTesting());
@@ -673,7 +673,7 @@
   base::RunLoop dialog_wait;
   js_dialog_manager->SetDialogShownCallbackForTesting(
       dialog_wait.QuitClosure());
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"alert('one'); alert('two');", base::NullCallback());
   dialog_wait.Run();
   EXPECT_TRUE(js_dialog_manager->IsShowingDialogForTesting());
@@ -684,7 +684,7 @@
   EXPECT_FALSE(js_dialog_manager->IsShowingDialogForTesting());
 
   // Make sure input events still work in the renderer process.
-  EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()->GetProcess()->IsBlocked());
 }
 
 // Similar to CrossProcessNavCancelsDialogs, with a renderer-initiated main
@@ -717,7 +717,7 @@
   EXPECT_FALSE(js_dialog_manager->IsShowingDialogForTesting());
 
   // Make sure input events still work in the renderer process.
-  EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()->GetProcess()->IsBlocked());
 }
 
 // Ensures that a download can complete while a dialog is showing, because it
@@ -764,7 +764,7 @@
   EXPECT_FALSE(js_dialog_manager->IsShowingDialogForTesting());
 
   // Make sure input events still work in the renderer process.
-  EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked());
+  EXPECT_FALSE(contents->GetPrimaryMainFrame()->GetProcess()->IsBlocked());
 }
 
 #if BUILDFLAG(IS_MAC)
@@ -784,7 +784,7 @@
   content::PrepContentsForBeforeUnloadTest(contents);
 
   // Start a navigation to trigger the beforeunload dialog.
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"window.location.href = 'about:blank'", base::NullCallback());
   AppModalDialogController* alert = ui_test_utils::WaitForAppModalDialog();
   EXPECT_TRUE(alert->IsValid());
@@ -793,7 +793,7 @@
 
   // Crash the renderer process and ensure the dialog is gone.
   content::RenderProcessHost* child_process =
-      contents->GetMainFrame()->GetProcess();
+      contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   child_process->Shutdown(0);
@@ -818,7 +818,7 @@
   base::RunLoop dialog_wait;
   js_dialog_manager->SetDialogShownCallbackForTesting(
       dialog_wait.QuitClosure());
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"f = document.createElement('iframe');"
       u"f.srcdoc = '<script>alert(1)</script>';"
       u"document.body.appendChild(f);",
@@ -828,7 +828,7 @@
 
   // Crash the renderer process and ensure the dialog is gone.
   content::RenderProcessHost* child_process =
-      contents->GetMainFrame()->GetProcess();
+      contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   child_process->Shutdown(0);
@@ -858,8 +858,8 @@
   EXPECT_FALSE(contents->IsLoading());
 
   // Clear the beforeunload handler so the test can easily exit.
-  contents->GetMainFrame()->ExecuteJavaScriptForTests(u"onbeforeunload=null;",
-                                                      base::NullCallback());
+  contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+      u"onbeforeunload=null;", base::NullCallback());
 }
 
 // Test for crbug.com/11647.  A page closed with window.close() should not have
@@ -870,7 +870,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptWithUserGestureForTests(kOpenNewBeforeUnloadPage,
                                                  base::NullCallback());
 
@@ -880,7 +880,7 @@
   browser()
       ->tab_strip_model()
       ->GetWebContentsAt(0)
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->ExecuteJavaScriptWithUserGestureForTests(u"w.close(); alert('bar');",
                                                  base::NullCallback());
   AppModalDialogController* alert = ui_test_utils::WaitForAppModalDialog();
@@ -1064,7 +1064,8 @@
   // Start with an http URL.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), http_url));
   WebContents* oldtab = browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderProcessHost* process = oldtab->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* process =
+      oldtab->GetPrimaryMainFrame()->GetProcess();
 
   // Now open a tab to a blank page and redirect it cross-site.
   std::string dont_fork_popup = "w=window.open();";
@@ -1073,7 +1074,7 @@
   dont_fork_popup += "\";";
 
   ui_test_utils::TabAddedWaiter tab_add(browser());
-  EXPECT_TRUE(content::ExecJs(oldtab->GetMainFrame(), dont_fork_popup));
+  EXPECT_TRUE(content::ExecJs(oldtab->GetPrimaryMainFrame(), dont_fork_popup));
 
   // The tab should be created by the time the script finished running.
   ASSERT_EQ(2, browser()->tab_strip_model()->count());
@@ -1092,7 +1093,7 @@
   // Process of the (cross-site) popup window depends on whether
   // site-per-process mode is enabled or not.
   content::RenderProcessHost* popup_process =
-      newtab->GetMainFrame()->GetProcess();
+      newtab->GetPrimaryMainFrame()->GetProcess();
   if (content::AreAllSitesIsolatedForTesting())
     EXPECT_NE(process, popup_process);
   else
@@ -1102,7 +1103,7 @@
   std::string navigate_str = "document.location=\"";
   navigate_str += https_url.spec();
   navigate_str += "\";";
-  EXPECT_TRUE(content::ExecJs(oldtab->GetMainFrame(), navigate_str));
+  EXPECT_TRUE(content::ExecJs(oldtab->GetPrimaryMainFrame(), navigate_str));
 
   // The old tab should be in the middle of document.location navigation.
   EXPECT_TRUE(oldtab->IsLoading());
@@ -1115,7 +1116,7 @@
   // Whether original stays in the original process (when navigating to a
   // cross-site url) depends on whether site-per-process mode is enabled or not.
   content::RenderProcessHost* new_process =
-      newtab->GetMainFrame()->GetProcess();
+      newtab->GetPrimaryMainFrame()->GetProcess();
   if (content::AreAllSitesIsolatedForTesting()) {
     EXPECT_NE(process, new_process);
 
@@ -2410,7 +2411,7 @@
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderViewHost* prev_rvh =
-      web_contents->GetMainFrame()->GetRenderViewHost();
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
   const gfx::Size initial_wcv_size = web_contents->GetContainerBounds().size();
   RenderViewSizeObserver observer(web_contents, browser()->window());
 
@@ -2419,12 +2420,12 @@
       browser(), embedded_test_server()->GetURL("/title1.html")));
   ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
   // A new RenderViewHost should be created.
-  EXPECT_NE(prev_rvh, web_contents->GetMainFrame()->GetRenderViewHost());
-  prev_rvh = web_contents->GetMainFrame()->GetRenderViewHost();
+  EXPECT_NE(prev_rvh, web_contents->GetPrimaryMainFrame()->GetRenderViewHost());
+  prev_rvh = web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
   gfx::Size rwhv_create_size0, rwhv_commit_size0, wcv_commit_size0;
   observer.GetSizeForRenderViewHost(
-      web_contents->GetMainFrame()->GetRenderViewHost(), &rwhv_create_size0,
-      &rwhv_commit_size0, &wcv_commit_size0);
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost(),
+      &rwhv_create_size0, &rwhv_commit_size0, &wcv_commit_size0);
   EXPECT_EQ(gfx::Size(initial_wcv_size.width(), initial_wcv_size.height()),
             rwhv_create_size0);
   // When a navigation entry is committed, the size of RenderWidgetHostView
@@ -2454,11 +2455,11 @@
       browser(), https_test_server.GetURL("/title2.html")));
   ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
   // A new RenderVieHost should be created.
-  EXPECT_NE(prev_rvh, web_contents->GetMainFrame()->GetRenderViewHost());
+  EXPECT_NE(prev_rvh, web_contents->GetPrimaryMainFrame()->GetRenderViewHost());
   gfx::Size rwhv_create_size1, rwhv_commit_size1, wcv_commit_size1;
   observer.GetSizeForRenderViewHost(
-      web_contents->GetMainFrame()->GetRenderViewHost(), &rwhv_create_size1,
-      &rwhv_commit_size1, &wcv_commit_size1);
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost(),
+      &rwhv_create_size1, &rwhv_commit_size1, &wcv_commit_size1);
   EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1);
   EXPECT_EQ(rwhv_commit_size1,
             web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
@@ -2474,8 +2475,8 @@
   ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
   gfx::Size rwhv_create_size2, rwhv_commit_size2, wcv_commit_size2;
   observer.GetSizeForRenderViewHost(
-      web_contents->GetMainFrame()->GetRenderViewHost(), &rwhv_create_size2,
-      &rwhv_commit_size2, &wcv_commit_size2);
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost(),
+      &rwhv_create_size2, &rwhv_commit_size2, &wcv_commit_size2);
 
   // The behavior on OSX and Views is incorrect in this edge case, but they are
   // differently incorrect.
@@ -2568,7 +2569,7 @@
       u")').matches;})();";
   bool js_result = false;
   base::RunLoop run_loop;
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       function, base::BindLambdaForTesting([&](base::Value value) {
         DCHECK(value.is_bool());
         js_result = value.GetBool();
@@ -2709,7 +2710,8 @@
       static_cast<web_modal::WebContentsModalDialogManagerDelegate*>(browser());
 
   // Simulate the tab requesting fullscreen.
-  browser_as_wc_delegate->EnterFullscreenModeForTab(tab->GetMainFrame(), {});
+  browser_as_wc_delegate->EnterFullscreenModeForTab(tab->GetPrimaryMainFrame(),
+                                                    {});
   EXPECT_TRUE(browser_as_wc_delegate->IsFullscreenForTabOrPending(tab));
 
   // The tab gets a modal dialog.
@@ -2737,7 +2739,8 @@
   auto capture_handle =
       tab->IncrementCapturerCount(gfx::Size(1280, 720), /*stay_hidden=*/false,
                                   /*stay_awake=*/true);
-  browser_as_wc_delegate->EnterFullscreenModeForTab(tab->GetMainFrame(), {});
+  browser_as_wc_delegate->EnterFullscreenModeForTab(tab->GetPrimaryMainFrame(),
+                                                    {});
   EXPECT_TRUE(browser_as_wc_delegate->IsFullscreenForTabOrPending(tab));
 
   // The tab gets a modal dialog.
@@ -2811,8 +2814,9 @@
   {
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
 
-    content::RenderFrameDeletedObserver crash_observer(wc->GetMainFrame());
-    wc->GetMainFrame()->GetProcess()->Shutdown(1);
+    content::RenderFrameDeletedObserver crash_observer(
+        wc->GetPrimaryMainFrame());
+    wc->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
     crash_observer.WaitUntilDeleted();
   }
 
@@ -2835,8 +2839,8 @@
     loop.Run();
   }
   // The navigation has not completed, but the renderer has come alive.
-  EXPECT_TRUE(wc->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_EQ(wc->GetMainFrame()->GetLastCommittedURL().spec(), "");
+  EXPECT_TRUE(wc->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_EQ(wc->GetPrimaryMainFrame()->GetLastCommittedURL().spec(), "");
 
   // Now try to navigate to `url2`. We're currently trying to load `url1` since
   // the above navigation will be delayed. Going to `url2` should be a
@@ -2890,8 +2894,9 @@
   {
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
 
-    content::RenderFrameDeletedObserver crash_observer(wc->GetMainFrame());
-    wc->GetMainFrame()->GetProcess()->Shutdown(1);
+    content::RenderFrameDeletedObserver crash_observer(
+        wc->GetPrimaryMainFrame());
+    wc->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
     crash_observer.WaitUntilDeleted();
   }
 
@@ -2914,8 +2919,8 @@
     loop.Run();
   }
   // The navigation has not completed, but the renderer has come alive.
-  EXPECT_TRUE(wc->GetMainFrame()->IsRenderFrameLive());
-  EXPECT_EQ(wc->GetMainFrame()->GetLastCommittedURL().spec(), "");
+  EXPECT_TRUE(wc->GetPrimaryMainFrame()->IsRenderFrameLive());
+  EXPECT_EQ(wc->GetPrimaryMainFrame()->GetLastCommittedURL().spec(), "");
 
   content::NavigationHandleCommitObserver back_observer(wc, url1);
   // Now try to go back. We're currently at `url2` since the above navigation
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 6e04b7de..b292a6b1 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -568,7 +568,7 @@
     case IDC_VIEW_SOURCE:
       browser_->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame()
+          ->GetPrimaryMainFrame()
           ->ViewSource();
       break;
     case IDC_PRINT:
@@ -1340,9 +1340,9 @@
   command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW,
                                         web_app::CanPopOutWebApp(profile()));
 
-  bool is_isolated_app =
-      current_web_contents->GetMainFrame()->GetWebExposedIsolationLevel() >=
-      WebExposedIsolationLevel::kMaybeIsolatedApplication;
+  bool is_isolated_app = current_web_contents->GetPrimaryMainFrame()
+                             ->GetWebExposedIsolationLevel() >=
+                         WebExposedIsolationLevel::kMaybeIsolatedApplication;
   command_updater_.UpdateCommandEnabled(
       IDC_OPEN_IN_CHROME, IsWebAppOrCustomTab() && !is_isolated_app);
 
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index fa6e3e38..e9f1137f 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -52,7 +52,8 @@
     if (!contents)
       continue;
 
-    GURL site_url = contents->GetMainFrame()->GetSiteInstance()->GetSiteURL();
+    GURL site_url =
+        contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL();
     bool is_ntp = site_url == GURL(chrome::kChromeUINewTabPageURL) ||
                   site_url == GURL(chrome::kChromeUINewTabPageThirdPartyURL);
 
@@ -61,7 +62,7 @@
           InstantServiceFactory::GetForProfile(profile());
       if (instant_service) {
         content::RenderProcessHost* rph =
-            contents->GetMainFrame()->GetProcess();
+            contents->GetPrimaryMainFrame()->GetProcess();
         is_ntp = instant_service->IsInstantProcess(rph->GetID());
       }
     }
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc
index 125fdb7..b777e80 100644
--- a/chrome/browser/ui/browser_instant_controller_unittest.cc
+++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -113,7 +113,7 @@
     // Validate initial instant state.
     EXPECT_EQ(test.start_in_instant_process,
               instant_service_->IsInstantProcess(
-                  contents->GetMainFrame()->GetProcess()->GetID()))
+                  contents->GetPrimaryMainFrame()->GetProcess()->GetID()))
         << test.description;
 
     // Setup an observer to verify reload or absence thereof.
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index c8efe84..0f9760b 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -1087,12 +1087,13 @@
   // There is no navigation (to about:blank or something like that).
   EXPECT_FALSE(params.contents_to_insert->IsLoading());
 
-  ASSERT_TRUE(params.contents_to_insert->GetMainFrame());
-  EXPECT_TRUE(params.contents_to_insert->GetMainFrame()->IsRenderFrameLive());
+  ASSERT_TRUE(params.contents_to_insert->GetPrimaryMainFrame());
+  EXPECT_TRUE(
+      params.contents_to_insert->GetPrimaryMainFrame()->IsRenderFrameLive());
   EXPECT_TRUE(
       params.contents_to_insert->GetController().IsInitialBlankNavigation());
   int renderer_id =
-      params.contents_to_insert->GetMainFrame()->GetProcess()->GetID();
+      params.contents_to_insert->GetPrimaryMainFrame()->GetProcess()->GetID();
 
   // We should have one window, with one tab of WebContents differ from
   // params.target_contents.
@@ -1108,9 +1109,10 @@
   EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
             params.navigated_or_inserted_contents);
-  EXPECT_EQ(renderer_id, params.navigated_or_inserted_contents->GetMainFrame()
-                             ->GetProcess()
-                             ->GetID());
+  EXPECT_EQ(renderer_id,
+            params.navigated_or_inserted_contents->GetPrimaryMainFrame()
+                ->GetProcess()
+                ->GetID());
 
   // We should have one window, with two tabs.
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -1387,8 +1389,8 @@
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
 
     content::RenderFrameDeletedObserver crash_observer(
-        web_contents->GetMainFrame());
-    web_contents->GetMainFrame()->GetProcess()->Shutdown(1);
+        web_contents->GetPrimaryMainFrame());
+    web_contents->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
     crash_observer.WaitUntilDeleted();
   }
   EXPECT_TRUE(web_contents->IsCrashed());
@@ -1853,7 +1855,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
 
   // Retrieve the iframe.
-  content::RenderFrameHost* main_frame = tab->GetMainFrame();
+  content::RenderFrameHost* main_frame = tab->GetPrimaryMainFrame();
   content::RenderFrameHost* iframe = ChildFrameAt(main_frame, 0);
   ASSERT_TRUE(iframe);
 
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc
index bf51edb0..b78565d 100644
--- a/chrome/browser/ui/browser_unittest.cc
+++ b/chrome/browser/ui/browser_unittest.cc
@@ -106,7 +106,8 @@
   WebContentsTester::For(raw_contents1)->NavigateAndCommit(GURL("about:blank"));
   WebContentsTester::For(raw_contents1)->TestSetIsLoading(false);
 
-  raw_contents1->GetMainFrame()->GetView()->SetBackgroundColor(SK_ColorRED);
+  raw_contents1->GetPrimaryMainFrame()->GetView()->SetBackgroundColor(
+      SK_ColorRED);
 
   // Add a second tab in the background.
   std::unique_ptr<WebContents> contents2 = CreateTestWebContents();
@@ -116,9 +117,11 @@
   WebContentsTester::For(raw_contents2)->TestSetIsLoading(false);
 
   tab_strip_model->ActivateTabAt(1, {TabStripModel::GestureType::kOther});
-  ASSERT_TRUE(raw_contents2->GetMainFrame()->GetView()->GetBackgroundColor());
-  EXPECT_EQ(SK_ColorRED,
-            *raw_contents2->GetMainFrame()->GetView()->GetBackgroundColor());
+  ASSERT_TRUE(
+      raw_contents2->GetPrimaryMainFrame()->GetView()->GetBackgroundColor());
+  EXPECT_EQ(
+      SK_ColorRED,
+      *raw_contents2->GetPrimaryMainFrame()->GetView()->GetBackgroundColor());
 }
 
 #if BUILDFLAG(ENABLE_PRINTING)
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
index 91418bcf..c8bd920 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
@@ -59,7 +59,8 @@
     content::WebContents* web_contents = GetActiveTab();
 
     // Create a bubble with the given camera and microphone access state.
-    PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame())
+    PageSpecificContentSettings::GetForFrame(
+        web_contents->GetPrimaryMainFrame())
         ->OnMediaStreamPermissionSet(web_contents->GetLastCommittedURL(), state,
                                      std::string(), std::string(),
                                      std::string(), std::string());
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index c5d9c6b..80bf73e 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -95,7 +95,8 @@
   WebContentsTester::For(web_contents())->
       NavigateAndCommit(GURL("https://www.example.com"));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentBlocked(ContentSettingsType::IMAGES);
 
   std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
@@ -114,7 +115,8 @@
   WebContentsTester::For(web_contents())->
       NavigateAndCommit(GURL("https://www.example.com"));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentBlocked(ContentSettingsType::COOKIES);
 
   std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
@@ -131,8 +133,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentAllowed(ContentSettingsType::COOKIES);
   content_setting_bubble_model =
       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
@@ -161,7 +163,8 @@
       DisableDeviceEnumerationForTesting();
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   std::string request_host = "google.com";
   GURL security_origin("http://" + request_host);
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
@@ -215,7 +218,8 @@
       url, GURL(), ContentSettingsType::MEDIASTREAM_CAMERA, setting);
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
       PageSpecificContentSettings::MICROPHONE_ACCESSED |
       PageSpecificContentSettings::MICROPHONE_BLOCKED |
@@ -277,7 +281,8 @@
       url, GURL(), ContentSettingsType::MEDIASTREAM_MIC, setting);
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
       PageSpecificContentSettings::MICROPHONE_ACCESSED |
       PageSpecificContentSettings::MICROPHONE_BLOCKED;
@@ -370,7 +375,8 @@
       audio_devices);
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
       PageSpecificContentSettings::MICROPHONE_ACCESSED |
       PageSpecificContentSettings::MICROPHONE_BLOCKED;
@@ -502,7 +508,8 @@
       DisableDeviceEnumerationForTesting();
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   std::string request_host = "google.com";
   GURL security_origin("http://" + request_host);
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
@@ -576,7 +583,8 @@
       DisableDeviceEnumerationForTesting();
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   std::string request_host = "google.com";
   GURL security_origin("http://" + request_host);
   PageSpecificContentSettings::MicrophoneCameraState microphone_camera_state =
@@ -651,7 +659,8 @@
       DisableDeviceEnumerationForTesting();
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   std::string request_host = "google.com";
   GURL security_origin("http://" + request_host);
 
@@ -729,7 +738,8 @@
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   HostContentSettingsMap* settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
 
@@ -849,8 +859,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Go from block by default to allow by default to block by default.
   {
@@ -926,8 +936,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
   // Clear site-specific exceptions.
   settings_map->ClearSettingsForOneType(ContentSettingsType::GEOLOCATION);
 
@@ -999,7 +1009,8 @@
 TEST_F(ContentSettingBubbleModelTest, FileURL) {
   std::string file_url("file:///tmp/test.html");
   NavigateAndCommit(GURL(file_url));
-  PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame())
+  PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame())
       ->OnContentBlocked(ContentSettingsType::IMAGES);
   std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
@@ -1172,7 +1183,8 @@
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   HostContentSettingsMap* settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
 
@@ -1249,8 +1261,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Go from block by default to allow by default to block by default.
   {
@@ -1325,8 +1337,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Block by default but allow a specific site.
   {
@@ -1359,8 +1371,8 @@
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
   // Clear site-specific exceptions.
   settings_map->ClearSettingsForOneType(ContentSettingsType::SENSORS);
 
@@ -1398,7 +1410,8 @@
   const GURL url("https://www.example.test/");
   WebContentsTester::For(web_contents())->NavigateAndCommit(url);
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentBlocked(ContentSettingsType::POPUPS);
 
   blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents());
@@ -1432,7 +1445,8 @@
       NavigateAndCommit(GURL("https://www.example.com"));
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentBlocked(ContentSettingsType::COOKIES);
 
   std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
@@ -1449,7 +1463,8 @@
       NavigateAndCommit(GURL("about:blank"));
 
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   content_settings->OnContentBlocked(ContentSettingsType::COOKIES);
 
   std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 83683f5..b1b4226 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -459,7 +459,8 @@
   // If a content type is blocked by default and was accessed, display the
   // content blocked page action.
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!content_settings)
     return false;
 
@@ -516,7 +517,8 @@
 bool ContentSettingGeolocationImageModel::UpdateAndGetVisibility(
     WebContents* web_contents) {
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   set_should_auto_open_bubble(false);
   if (!content_settings)
     return false;
@@ -649,7 +651,8 @@
 bool ContentSettingMIDISysExImageModel::UpdateAndGetVisibility(
     WebContents* web_contents) {
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!content_settings)
     return false;
 
@@ -714,7 +717,8 @@
 bool ContentSettingClipboardReadWriteImageModel::UpdateAndGetVisibility(
     WebContents* web_contents) {
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!content_settings)
     return false;
   ContentSettingsType content_type = ContentSettingsType::CLIPBOARD_READ_WRITE;
@@ -739,7 +743,8 @@
     WebContents* web_contents) {
   set_should_auto_open_bubble(false);
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!content_settings)
     return false;
   state_ = content_settings->GetMicrophoneCameraState();
@@ -936,8 +941,8 @@
 
 bool ContentSettingSensorsImageModel::UpdateAndGetVisibility(
     WebContents* web_contents) {
-  auto* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+  auto* content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents->GetPrimaryMainFrame());
   if (!content_settings)
     return false;
 
@@ -979,7 +984,8 @@
 bool ContentSettingPopupImageModel::UpdateAndGetVisibility(
     WebContents* web_contents) {
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!content_settings || !content_settings->IsContentBlocked(content_type()))
     return false;
   set_icon(kWebIcon, vector_icons::kBlockedBadgeIcon);
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
index 8bf8c9f..647c63a 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
@@ -29,7 +29,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents->GetMainFrame());
+          web_contents->GetPrimaryMainFrame());
   content_settings->BlockAllContentForTesting();
 
   // Automatic downloads are handled by DownloadRequestLimiter.
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
index 61bee756..8346a5a 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
@@ -154,7 +154,8 @@
       std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
           web_contents()));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   auto content_setting_image_model =
       ContentSettingImageModel::CreateForContentType(
           ContentSettingImageModel::ImageType::IMAGES);
@@ -205,7 +206,8 @@
       origin, "A=B", base::Time::Now(), absl::nullopt /* server_time */,
       absl::nullopt /* cookie_partition_key */));
   ASSERT_TRUE(cookie);
-  PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame())
+  PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame())
       ->OnCookiesAccessed({content::CookieAccessDetails::Type::kChange,
                            origin,
                            origin,
@@ -227,7 +229,8 @@
       std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
           web_contents()));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
 
   auto content_setting_image_model =
       ContentSettingImageModel::CreateForContentType(
@@ -246,8 +249,8 @@
                              /* tooltip_empty = */ true);
 
   NavigateAndCommit(web_contents(), GURL("http://www.google.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Allowing by default but blocking (e.g. due to a permissions policy) causes
   // the indicator to be shown.
@@ -261,8 +264,8 @@
       /* explanatory_string_id = */ 0);
 
   NavigateAndCommit(web_contents(), GURL("http://www.google.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Blocking by default but allowing (e.g. via a site-specific exception)
   // causes the indicator to be shown.
@@ -276,8 +279,8 @@
       /* explanatory_string_id = */ 0);
 
   NavigateAndCommit(web_contents(), GURL("http://www.google.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Blocking access by default also causes the indicator to be shown so users
   // can set an exception.
@@ -311,7 +314,8 @@
   GURL requesting_origin = GURL("https://www.example.com");
   NavigateAndCommit(web_contents(), requesting_origin);
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   HostContentSettingsMap* settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
 
@@ -371,7 +375,8 @@
   GURL requesting_origin = GURL("https://www.example.com");
   NavigateAndCommit(web_contents(), requesting_origin);
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   HostContentSettingsMap* settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
 
@@ -419,7 +424,8 @@
   GURL requesting_origin = GURL("https://www.example.com");
   NavigateAndCommit(web_contents(), requesting_origin);
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
 
   auto content_setting_image_model =
       ContentSettingImageModel::CreateForContentType(
@@ -483,7 +489,8 @@
           web_contents()));
   NavigateAndCommit(web_contents(), GURL("https://www.example.com"));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   HostContentSettingsMap* settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile());
 
@@ -520,8 +527,8 @@
   }
 
   NavigateAndCommit(web_contents(), GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Go from block by default to allow by default to block by default.
   {
@@ -549,8 +556,8 @@
   }
 
   NavigateAndCommit(web_contents(), GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
 
   // Block by default but allow a specific site.
   {
@@ -568,8 +575,8 @@
   }
 
   NavigateAndCommit(web_contents(), GURL("https://www.example.com"));
-  content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+  content_settings = PageSpecificContentSettings::GetForFrame(
+      web_contents()->GetPrimaryMainFrame());
   // Clear site-specific exceptions.
   settings_map->ClearSettingsForOneType(ContentSettingsType::SENSORS);
 
@@ -593,7 +600,7 @@
 TEST_F(ContentSettingImageModelTest, NULLPageSpecificContentSettings) {
   PageSpecificContentSettings::DeleteForWebContentsForTest(web_contents());
   EXPECT_EQ(nullptr, PageSpecificContentSettings::GetForFrame(
-                         web_contents()->GetMainFrame()));
+                         web_contents()->GetPrimaryMainFrame()));
   // Should not crash.
   ContentSettingImageModel::CreateForContentType(
       ContentSettingImageModel::ImageType::IMAGES)
@@ -606,7 +613,8 @@
       std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
           web_contents()));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   auto content_setting_image_model =
       ContentSettingImageModel::CreateForContentType(
           ContentSettingImageModel::ImageType::ADS);
@@ -625,7 +633,8 @@
       std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
           web_contents()));
   PageSpecificContentSettings* content_settings =
-      PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame());
+      PageSpecificContentSettings::GetForFrame(
+          web_contents()->GetPrimaryMainFrame());
   auto content_setting_image_model =
       ContentSettingImageModel::CreateForContentType(
           ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
@@ -660,7 +669,7 @@
       ContentSettingImageModel::CreateForContentType(
           ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
   EXPECT_FALSE(content_setting_image_model->is_visible());
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   content_setting_image_model->Update(web_contents());
@@ -684,7 +693,7 @@
       std::make_unique<TestQuietNotificationPermissionUiSelector>(
           permissions::PermissionUiSelector::QuietUiReason::
               kTriggeredByCrowdDeny));
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   content_setting_image_model->Update(web_contents());
@@ -705,7 +714,7 @@
       std::make_unique<TestQuietNotificationPermissionUiSelector>(
           permissions::PermissionUiSelector::QuietUiReason::
               kTriggeredDueToAbusiveRequests));
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   content_setting_image_model->Update(web_contents());
@@ -726,7 +735,7 @@
       std::make_unique<TestQuietNotificationPermissionUiSelector>(
           permissions::PermissionUiSelector::QuietUiReason::
               kTriggeredDueToAbusiveContent));
-  manager_->AddRequest(web_contents()->GetMainFrame(), &request_);
+  manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_);
   WaitForBubbleToBeShown();
   EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
   content_setting_image_model->Update(web_contents());
diff --git a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
index 373c330..227a7c70 100644
--- a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
+++ b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
@@ -121,7 +121,7 @@
     NavigateIframeToUrlWithoutGesture(GetWebContents(), "test", child_url);
 
     content::RenderFrameHost* child =
-        content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0);
+        content::ChildFrameAt(GetWebContents()->GetPrimaryMainFrame(), 0);
     EXPECT_EQ(child_url, child->GetLastCommittedURL());
 
     const GURL redirect_url =
@@ -303,7 +303,7 @@
       embedded_test_server()->GetURL("a.com", "/title1.html"));
 
   content::RenderFrameHost* child =
-      content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0);
+      content::ChildFrameAt(GetWebContents()->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
 
   GURL redirect_url = embedded_test_server()->GetURL("b.com", "/title1.html");
@@ -335,7 +335,7 @@
       embedded_test_server()->GetURL("a.com", "/title1.html"));
 
   content::RenderFrameHost* child =
-      content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0);
+      content::ChildFrameAt(GetWebContents()->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
 
   GURL redirect_url = embedded_test_server()->GetURL("b.com", "/title1.html");
@@ -403,7 +403,7 @@
   ~FramebustBlockFencedFrameTest() override = default;
 
   content::RenderFrameHost* primary_main_frame_host() {
-    return GetWebContents()->GetMainFrame();
+    return GetWebContents()->GetPrimaryMainFrame();
   }
 
  protected:
diff --git a/chrome/browser/ui/cookie_controls/cookie_controls_controller_unittest.cc b/chrome/browser/ui/cookie_controls/cookie_controls_controller_unittest.cc
index 5adacf0..96856993 100644
--- a/chrome/browser/ui/cookie_controls/cookie_controls_controller_unittest.cc
+++ b/chrome/browser/ui/cookie_controls/cookie_controls_controller_unittest.cc
@@ -103,7 +103,7 @@
   content_settings::PageSpecificContentSettings*
   page_specific_content_settings() {
     return content_settings::PageSpecificContentSettings::GetForFrame(
-        web_contents()->GetMainFrame());
+        web_contents()->GetPrimaryMainFrame());
   }
 
  private:
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_test.cc b/chrome/browser/ui/exclusive_access/exclusive_access_test.cc
index 33720bafa7..8efc47ae 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_test.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_test.cc
@@ -192,7 +192,7 @@
 void ExclusiveAccessTest::EnterActiveTabFullscreen() {
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   FullscreenNotificationObserver fullscreen_observer(browser());
-  browser()->EnterFullscreenModeForTab(tab->GetMainFrame(), {});
+  browser()->EnterFullscreenModeForTab(tab->GetPrimaryMainFrame(), {});
   fullscreen_observer.Wait();
 }
 
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
index c0ee7d4..d1dd6925 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
@@ -47,7 +47,10 @@
       base::FilePath(kEmptyFile)));
   ASSERT_TRUE(AddTabAtIndex(0, file_url, PAGE_TRANSITION_TYPED));
   GetFullscreenController()->EnterFullscreenModeForTab(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+      browser()
+          ->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame());
   ASSERT_TRUE(IsExclusiveAccessBubbleDisplayed());
 }
 
@@ -478,5 +481,8 @@
                        EnterFullscreenWhenInFullscreen) {
   EnterActiveTabFullscreen();
   EXPECT_TRUE(GetFullscreenController()->CanEnterFullscreenModeForTab(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()));
+      browser()
+          ->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame()));
 }
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
index b4a6e1d5..a1dcaac 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -87,7 +87,7 @@
     EXPECT_TRUE(browser()->IsMouseLocked() == browser()
                                                   ->tab_strip_model()
                                                   ->GetActiveWebContents()
-                                                  ->GetMainFrame()
+                                                  ->GetPrimaryMainFrame()
                                                   ->GetRenderViewHost()
                                                   ->GetWidget()
                                                   ->GetView()
@@ -147,7 +147,7 @@
   do {
     FullscreenNotificationObserver fullscreen_observer(browser());
     if (enter_fullscreen)
-      browser()->EnterFullscreenModeForTab(tab->GetMainFrame(), {});
+      browser()->EnterFullscreenModeForTab(tab->GetPrimaryMainFrame(), {});
     else
       browser()->ExitFullscreenModeForTab(tab);
     fullscreen_observer.Wait();
@@ -207,7 +207,8 @@
 IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest,
                        RunOrDeferClosureDuringTransition) {
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  GetFullscreenController()->EnterFullscreenModeForTab(tab->GetMainFrame(), {});
+  GetFullscreenController()->EnterFullscreenModeForTab(
+      tab->GetPrimaryMainFrame(), {});
   ASSERT_TRUE(IsWindowFullscreenForTabOrPending());
 
   base::RunLoop run_loop;
@@ -713,7 +714,7 @@
     EXPECT_NE(popup, browser);
     content::WebContents* popup_contents =
         popup->tab_strip_model()->GetActiveWebContents();
-    EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetMainFrame()));
+    EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetPrimaryMainFrame()));
     EXPECT_TRUE(content::WaitForLoadStop(popup_contents));
     return popup_contents;
   }
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
index 9c6a4a89..3ea83f3 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_test.cc
@@ -278,9 +278,9 @@
           GetBrowser()->tab_strip_model()->GetActiveWebContents();
       if (event == TAB_FULLSCREEN_TRUE) {
         if (GetFullscreenController()->CanEnterFullscreenModeForTab(
-                active_tab->GetMainFrame())) {
+                active_tab->GetPrimaryMainFrame())) {
           GetFullscreenController()->EnterFullscreenModeForTab(
-              active_tab->GetMainFrame());
+              active_tab->GetPrimaryMainFrame());
         }
       } else {
         GetFullscreenController()->ExitFullscreenModeForTab(active_tab);
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc
index d35444b..e6d624b 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc
@@ -90,7 +90,7 @@
   GURL url = embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
 
   // Make the top page fullscreen.
@@ -130,7 +130,7 @@
   GURL url = embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(a{allowfullscreen})");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
   content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
 
   // Make the top page fullscreen.
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
index 722d6ab4..e98be66c 100644
--- a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
+++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
@@ -166,7 +166,7 @@
 
   content::RenderWidgetHostView* mouse_lock_view = nullptr;
   RenderViewHost* const rvh =
-      exclusive_access_tab()->GetMainFrame()->GetRenderViewHost();
+      exclusive_access_tab()->GetPrimaryMainFrame()->GetRenderViewHost();
   if (rvh)
     mouse_lock_view = rvh->GetWidget()->GetView();
 
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index d8b3f04..8f7bd9b6 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -361,7 +361,7 @@
             params.page_url = app_contents->GetLastCommittedURL();
             params.link_url = target_url;
 
-            TestRenderViewContextMenu menu(*app_contents->GetMainFrame(),
+            TestRenderViewContextMenu menu(*app_contents->GetPrimaryMainFrame(),
                                            params);
             menu.Init();
             menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB,
@@ -682,7 +682,8 @@
 
   // Ensure that the frame navigated successfully and that it has correct
   // content.
-  RenderFrameHost* subframe = content::ChildFrameAt(tab->GetMainFrame(), 0);
+  RenderFrameHost* subframe =
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(app_url, subframe->GetLastCommittedURL());
   EXPECT_EQ(
       "This page has no title.",
@@ -822,7 +823,7 @@
     ASSERT_TRUE(new_tab);
     EXPECT_TRUE(WaitForLoadStop(new_tab));
     EXPECT_EQ(url, new_tab->GetLastCommittedURL());
-    RenderFrameHost* new_rfh = new_tab->GetMainFrame();
+    RenderFrameHost* new_rfh = new_tab->GetPrimaryMainFrame();
 
     EXPECT_EQ(expect_same_process, rfh->GetProcess() == new_rfh->GetProcess())
         << " for " << url << " from " << rfh->GetLastCommittedURL();
@@ -928,7 +929,7 @@
         web_contents->GetPrimaryPage(),
         base::BindRepeating(&content::FrameMatchesName, name));
   };
-  RenderFrameHost* app = web_contents->GetMainFrame();
+  RenderFrameHost* app = web_contents->GetPrimaryMainFrame();
   RenderFrameHost* same_dir = find_frame("SameOrigin-SamePath");
   RenderFrameHost* diff_dir = find_frame("SameOrigin-DifferentPath");
   RenderFrameHost* same_site = find_frame("OtherSubdomain-SameSite");
@@ -1042,7 +1043,7 @@
       app_browser_->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
 
-  RenderFrameHost* app = web_contents->GetMainFrame();
+  RenderFrameHost* app = web_contents->GetPrimaryMainFrame();
 
   // Add a data: URL subframe.  This should stay in the app process.
   TestSubframeProcess(app, GURL("data:text/html,foo"), "test_iframe",
@@ -1112,7 +1113,7 @@
         web_contents->GetPrimaryPage(),
         base::BindRepeating(&content::FrameMatchesName, name));
   };
-  RenderFrameHost* app = web_contents->GetMainFrame();
+  RenderFrameHost* app = web_contents->GetPrimaryMainFrame();
   RenderFrameHost* same_dir = find_frame("SameOrigin-SamePath");
   RenderFrameHost* diff_dir = find_frame("SameOrigin-DifferentPath");
   RenderFrameHost* same_site = find_frame("OtherSubdomain-SameSite");
@@ -1204,7 +1205,7 @@
   {
     SCOPED_TRACE("... from diff_dir");
     ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, diff_dir_url_));
-    RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_FALSE(main_frame->GetSiteInstance()->GetSiteURL().SchemeIs(
         extensions::kExtensionScheme));
     TestPopupProcess(main_frame, app_url, false, true);
@@ -1220,7 +1221,7 @@
   {
     SCOPED_TRACE("... from same_site");
     ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, same_site_url_));
-    RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_FALSE(main_frame->GetSiteInstance()->GetSiteURL().SchemeIs(
         extensions::kExtensionScheme));
     TestPopupProcess(main_frame, app_url, false, true);
@@ -1237,7 +1238,7 @@
     SCOPED_TRACE("... from isolated_url");
     ASSERT_TRUE(
         ui_test_utils::NavigateToURL(app_browser_, isolated_url_outside_app_));
-    RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_FALSE(main_frame->GetSiteInstance()->GetSiteURL().SchemeIs(
         extensions::kExtensionScheme));
     TestPopupProcess(main_frame, app_url, false, true);
@@ -1253,7 +1254,7 @@
   {
     SCOPED_TRACE("... from cross_site");
     ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, cross_site_url_));
-    RenderFrameHost* main_frame = web_contents->GetMainFrame();
+    RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
     EXPECT_FALSE(main_frame->GetSiteInstance()->GetSiteURL().SchemeIs(
         extensions::kExtensionScheme));
     TestPopupProcess(main_frame, app_url, false, true);
@@ -1315,7 +1316,7 @@
       ui_test_utils::NavigateToURL(browser(), double_slash_path_app_url));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  RenderFrameHost* main_frame = contents->GetMainFrame();
+  RenderFrameHost* main_frame = contents->GetPrimaryMainFrame();
   EXPECT_EQ(double_slash_path_app_url, main_frame->GetLastCommittedURL());
 
   // The resulting page should load in an app process, and the corresponding
@@ -1380,7 +1381,7 @@
 
   // Check that the app loaded properly. Even though its URL is from an
   // isolated origin (isolated.com), it should go into an app process.
-  RenderFrameHost* app = web_contents->GetMainFrame();
+  RenderFrameHost* app = web_contents->GetPrimaryMainFrame();
   EXPECT_EQ(extensions::kExtensionScheme,
             app->GetSiteInstance()->GetSiteURL().scheme());
   GURL app_site =
@@ -1421,12 +1422,12 @@
   // processes to a non-app process.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, very_isolated_url));
   EXPECT_FALSE(process_map_->Contains(
-      web_contents->GetMainFrame()->GetProcess()->GetID()));
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Navigating main frame back to the app URL should go into an app process.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, app_url));
   EXPECT_TRUE(process_map_->Contains(
-      web_contents->GetMainFrame()->GetProcess()->GetID()));
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 }
 
 // Check that when a hosted app's extent contains multiple origins, one of
@@ -1461,7 +1462,7 @@
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
 
   // The app URL should have loaded in an app process.
-  RenderFrameHost* app = web_contents->GetMainFrame();
+  RenderFrameHost* app = web_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(process_map_->Contains(app->GetProcess()->GetID()));
   EXPECT_EQ(extensions::kExtensionScheme,
             app->GetSiteInstance()->GetSiteURL().scheme());
@@ -1483,9 +1484,9 @@
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(app_browser_, unisolated_app_url));
   EXPECT_TRUE(process_map_->Contains(
-      web_contents->GetMainFrame()->GetProcess()->GetID()));
+      web_contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
   EXPECT_NE(first_app_process_id,
-            web_contents->GetMainFrame()->GetProcess()->GetID());
+            web_contents->GetPrimaryMainFrame()->GetProcess()->GetID());
 }
 
 class HostedAppSitePerProcessTest : public HostedAppProcessModelTest {
@@ -1544,15 +1545,15 @@
   EXPECT_TRUE(content::WaitForLoadStop(bar_contents));
 
   EXPECT_NE(foo_contents, bar_contents);
-  EXPECT_NE(foo_contents->GetMainFrame()->GetSiteInstance(),
-            bar_contents->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(foo_contents->GetPrimaryMainFrame()->GetSiteInstance(),
+            bar_contents->GetPrimaryMainFrame()->GetSiteInstance());
   EXPECT_EQ(foo_app_url, foo_contents->GetLastCommittedURL());
   EXPECT_EQ(bar_app_url, bar_contents->GetLastCommittedURL());
 
   // Under --site-per-process the two apps should load in separate processes,
   // even when over process limit.
-  EXPECT_NE(foo_contents->GetMainFrame()->GetProcess(),
-            bar_contents->GetMainFrame()->GetProcess());
+  EXPECT_NE(foo_contents->GetPrimaryMainFrame()->GetProcess(),
+            bar_contents->GetPrimaryMainFrame()->GetProcess());
 }
 
 // Check that when a hosted app covers multiple sites in its web extent, these
@@ -1595,12 +1596,12 @@
 
   // Ensure the two pages don't share a process despite being from the same
   // app, since they are from different sites.
-  EXPECT_NE(foo_contents->GetMainFrame()->GetSiteInstance(),
-            bar_contents->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(foo_contents->GetPrimaryMainFrame()->GetSiteInstance(),
+            bar_contents->GetPrimaryMainFrame()->GetSiteInstance());
   auto* foo_process =
-      foo_contents->GetMainFrame()->GetSiteInstance()->GetProcess();
+      foo_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetProcess();
   auto* bar_process =
-      bar_contents->GetMainFrame()->GetSiteInstance()->GetProcess();
+      bar_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetProcess();
   EXPECT_NE(foo_process, bar_process);
 
   // Ensure each process only has access to its site's data.
@@ -1711,7 +1712,7 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     EXPECT_EQ(jit_disabled_app_url, web_contents->GetLastCommittedURL());
     scoped_refptr<content::SiteInstance> site_instance =
-        web_contents->GetMainFrame()->GetSiteInstance();
+        web_contents->GetPrimaryMainFrame()->GetSiteInstance();
     EXPECT_TRUE(
         site_instance->GetSiteURL().SchemeIs(extensions::kExtensionScheme));
     EXPECT_TRUE(site_instance->GetProcess()->IsJitDisabled());
@@ -1722,7 +1723,7 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), jit_enabled_app_url));
     web_contents = browser()->tab_strip_model()->GetActiveWebContents();
     EXPECT_EQ(jit_enabled_app_url, web_contents->GetLastCommittedURL());
-    site_instance = web_contents->GetMainFrame()->GetSiteInstance();
+    site_instance = web_contents->GetPrimaryMainFrame()->GetSiteInstance();
     EXPECT_TRUE(
         site_instance->GetSiteURL().SchemeIs(extensions::kExtensionScheme));
     EXPECT_FALSE(site_instance->GetProcess()->IsJitDisabled());
@@ -1775,7 +1776,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(foo_app_url, web_contents->GetLastCommittedURL());
   scoped_refptr<content::SiteInstance> foo_site_instance =
-      web_contents->GetMainFrame()->GetSiteInstance();
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   auto* foo_process = foo_site_instance->GetProcess();
   auto* process_map = extensions::ProcessMap::Get(browser()->profile());
   EXPECT_TRUE(process_map->Contains(foo_process->GetID()));
@@ -1802,7 +1803,7 @@
   }
   EXPECT_EQ(bar_app_url, web_contents->GetLastCommittedURL());
   scoped_refptr<content::SiteInstance> bar_site_instance =
-      web_contents->GetMainFrame()->GetSiteInstance();
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_NE(foo_site_instance, bar_site_instance);
   auto* bar_process = bar_site_instance->GetProcess();
   EXPECT_TRUE(process_map->Contains(bar_process->GetID()));
@@ -1822,7 +1823,7 @@
   // there's a process swap from an app to a non-app process.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), foo_app_url));
   EXPECT_EQ(foo_app_url, web_contents->GetLastCommittedURL());
-  foo_site_instance = web_contents->GetMainFrame()->GetSiteInstance();
+  foo_site_instance = web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   foo_process = foo_site_instance->GetProcess();
   EXPECT_TRUE(process_map->Contains(foo_process->GetID()));
 
@@ -1835,8 +1836,9 @@
     observer.Wait();
   }
   EXPECT_EQ(foo_nonapp_url, web_contents->GetLastCommittedURL());
-  EXPECT_NE(foo_site_instance, web_contents->GetMainFrame()->GetSiteInstance());
-  auto* foo_nonapp_process = web_contents->GetMainFrame()->GetProcess();
+  EXPECT_NE(foo_site_instance,
+            web_contents->GetPrimaryMainFrame()->GetSiteInstance());
+  auto* foo_nonapp_process = web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_NE(foo_process, foo_nonapp_process);
   EXPECT_FALSE(process_map->Contains(foo_nonapp_process->GetID()));
 
@@ -1904,14 +1906,16 @@
 
   // The two foo.com tabs should be in the same process even though they are
   // unrelated, since hosted apps use the process-per-site process model.
-  auto* foo_process = foo_contents->GetMainFrame()->GetProcess();
-  EXPECT_EQ(foo_process, foo_contents2->GetMainFrame()->GetProcess());
+  auto* foo_process = foo_contents->GetPrimaryMainFrame()->GetProcess();
+  EXPECT_EQ(foo_process, foo_contents2->GetPrimaryMainFrame()->GetProcess());
   EXPECT_FALSE(
-      foo_contents->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-          foo_contents2->GetMainFrame()->GetSiteInstance()));
+      foo_contents->GetPrimaryMainFrame()
+          ->GetSiteInstance()
+          ->IsRelatedSiteInstance(
+              foo_contents2->GetPrimaryMainFrame()->GetSiteInstance()));
 
   // The bar.com tab should be in a different process from the foo.com tabs.
-  auto* bar_process = bar_contents->GetMainFrame()->GetProcess();
+  auto* bar_process = bar_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_NE(foo_process, bar_process);
 
   // Ensure all tabs are in app processes.
@@ -1963,10 +1967,12 @@
   content::WebContents* bar_contents2 =
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(bar_app_url2, bar_contents2->GetLastCommittedURL());
-  EXPECT_EQ(bar_process, bar_contents2->GetMainFrame()->GetProcess());
+  EXPECT_EQ(bar_process, bar_contents2->GetPrimaryMainFrame()->GetProcess());
   EXPECT_FALSE(
-      bar_contents->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
-          bar_contents2->GetMainFrame()->GetSiteInstance()));
+      bar_contents->GetPrimaryMainFrame()
+          ->GetSiteInstance()
+          ->IsRelatedSiteInstance(
+              bar_contents2->GetPrimaryMainFrame()->GetSiteInstance()));
 
   // Ensure bar.com tabs can open and script their open background page.
   {
@@ -2074,9 +2080,9 @@
     EXPECT_TRUE(content::WaitForLoadStop(web_contents));
     // Verify we didn't get an error page.
     EXPECT_EQ(main_origin_url,
-              web_contents->GetMainFrame()->GetLastCommittedURL());
+              web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
     EXPECT_EQ(url::Origin::Create(main_origin_url),
-              web_contents->GetMainFrame()->GetLastCommittedOrigin());
+              web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
     // If we get here without a crash, the test has passed.
   }
 };
diff --git a/chrome/browser/ui/global_media_controls/media_notification_service.cc b/chrome/browser/ui/global_media_controls/media_notification_service.cc
index fa353a8b..824f59d 100644
--- a/chrome/browser/ui/global_media_controls/media_notification_service.cc
+++ b/chrome/browser/ui/global_media_controls/media_notification_service.cc
@@ -244,7 +244,8 @@
                             IsWebContentsFocused(web_contents));
 
   ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get();
-  ukm::SourceId source_id = web_contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
   if (++actions_recorded_to_ukm_[source_id] > kMaxActionsRecordedToUKM)
     return;
diff --git a/chrome/browser/ui/hats/hats_helper_unittest.cc b/chrome/browser/ui/hats/hats_helper_unittest.cc
index 743fe45..6ed9901c 100644
--- a/chrome/browser/ui/hats/hats_helper_unittest.cc
+++ b/chrome/browser/ui/hats/hats_helper_unittest.cc
@@ -48,7 +48,9 @@
     return content::WebContentsTester::For(web_contents_.get());
   }
 
-  content::RenderFrameHost* main_rfh() { return web_contents_->GetMainFrame(); }
+  content::RenderFrameHost* main_rfh() {
+    return web_contents_->GetPrimaryMainFrame();
+  }
 
  private:
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
index 354c22c..911aeb7 100644
--- a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
+++ b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
@@ -35,17 +35,18 @@
   content::RenderFrameHost* result = nullptr;
   // We only consider frames visible to the user for hung frames. This is
   // fine because only frames receiving input are considered hung.
-  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
-      [](const content::RenderProcessHost* hung_process,
-         content::RenderFrameHost** result,
-         content::RenderFrameHost* render_frame_host) {
-        if (render_frame_host->GetProcess() == hung_process) {
-          *result = render_frame_host;
-          return content::RenderFrameHost::FrameIterationAction::kStop;
-        }
-        return content::RenderFrameHost::FrameIterationAction::kContinue;
-      },
-      hung_process, &result));
+  web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      base::BindRepeating(
+          [](const content::RenderProcessHost* hung_process,
+             content::RenderFrameHost** result,
+             content::RenderFrameHost* render_frame_host) {
+            if (render_frame_host->GetProcess() == hung_process) {
+              *result = render_frame_host;
+              return content::RenderFrameHost::FrameIterationAction::kStop;
+            }
+            return content::RenderFrameHost::FrameIterationAction::kContinue;
+          },
+          hung_process, &result));
   return result;
 }
 
@@ -112,7 +113,8 @@
   // http://crbug.com/6726 for more information.
   base::i18n::AdjustStringForLocaleDirection(&page_title);
 
-  if (affected_web_contents->GetMainFrame()->GetProcess() == hung_process)
+  if (affected_web_contents->GetPrimaryMainFrame()->GetProcess() ==
+      hung_process)
     return page_title;
 
   GURL hung_url = GetURLOfAnyHungFrame(affected_web_contents, hung_process);
diff --git a/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc b/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc
index a6bed95..790025c 100644
--- a/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc
+++ b/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc
@@ -47,9 +47,10 @@
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   TabDialogs::FromWebContents(active_web_contents)
-      ->ShowHungRendererDialog(
-          active_web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget(),
-          base::DoNothing());
+      ->ShowHungRendererDialog(active_web_contents->GetPrimaryMainFrame()
+                                   ->GetRenderViewHost()
+                                   ->GetWidget(),
+                               base::DoNothing());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("b.com", "/title2.html")));
   // Expect that the dialog has been dismissed.
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
index 28a7229..e8c115f 100644
--- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
+++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
@@ -58,8 +58,8 @@
   scoped_refptr<content::MessageLoopRunner> runner =
       new content::MessageLoopRunner;
   js_helper->SetDialogShownCallbackForTesting(runner->QuitClosure());
-  tab->GetMainFrame()->ExecuteJavaScriptForTests(u"alert()",
-                                                 base::NullCallback());
+  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
+                                                        base::NullCallback());
   runner->Run();
 
   // Try reloading.
@@ -80,12 +80,12 @@
   content::WebContents* tab1 =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::WebContentsAddedObserver new_wc_observer;
-  tab1->GetMainFrame()->ExecuteJavaScriptForTests(
+  tab1->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"window.open('about:blank');", base::NullCallback());
   content::WebContents* tab2 = new_wc_observer.GetWebContents();
   ASSERT_NE(tab1, tab2);
-  ASSERT_EQ(tab1->GetMainFrame()->GetProcess(),
-            tab2->GetMainFrame()->GetProcess());
+  ASSERT_EQ(tab1->GetPrimaryMainFrame()->GetProcess(),
+            tab2->GetPrimaryMainFrame()->GetProcess());
 
   // Tab two shows a dialog.
   scoped_refptr<content::MessageLoopRunner> runner =
@@ -93,8 +93,8 @@
   javascript_dialogs::TabModalDialogManager* js_helper2 =
       javascript_dialogs::TabModalDialogManager::FromWebContents(tab2);
   js_helper2->SetDialogShownCallbackForTesting(runner->QuitClosure());
-  tab2->GetMainFrame()->ExecuteJavaScriptForTests(u"alert()",
-                                                  base::NullCallback());
+  tab2->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
+                                                         base::NullCallback());
   runner->Run();
 
   // Tab two is closed while the dialog is up.
@@ -124,8 +124,8 @@
   scoped_refptr<content::MessageLoopRunner> runner =
       new content::MessageLoopRunner;
   js_helper->SetDialogShownCallbackForTesting(runner->QuitClosure());
-  tab->GetMainFrame()->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script),
-                                                 base::NullCallback());
+  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
+      base::UTF8ToUTF16(script), base::NullCallback());
   runner->Run();
 
   // The tab is closed while the dialog is up.
@@ -161,7 +161,7 @@
 IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, HandleJavaScriptDialog) {
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* frame = tab->GetMainFrame();
+  content::RenderFrameHost* frame = tab->GetPrimaryMainFrame();
   javascript_dialogs::TabModalDialogManager* js_helper =
       javascript_dialogs::TabModalDialogManager::FromWebContents(tab);
 
@@ -228,7 +228,7 @@
  public:
   explicit JavaScriptDialogDismissalCauseTester(JavaScriptDialogTest* test)
       : tab_(test->browser()->tab_strip_model()->GetActiveWebContents()),
-        frame_(tab_->GetMainFrame()),
+        frame_(tab_->GetPrimaryMainFrame()),
         js_helper_(
             javascript_dialogs::TabModalDialogManager::FromWebContents(tab_)) {
     js_helper_->SetDialogDismissedCallbackForTesting(base::BindOnce(
@@ -423,7 +423,7 @@
   }
 
   content::RenderFrameHost* subframe =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(subframe);
 
   // Verify the title that would be used for a dialog spawned by that subframe.
@@ -473,10 +473,10 @@
   prerender_helper_.AddPrerenderAsync(prerender_url);
 
   // Show an alert dialog
-  js_helper->RunJavaScriptDialog(web_contents_, web_contents_->GetMainFrame(),
-                                 content::JAVASCRIPT_DIALOG_TYPE_ALERT,
-                                 std::u16string(), std::u16string(),
-                                 callback_helper.GetCallback(), &did_suppress);
+  js_helper->RunJavaScriptDialog(
+      web_contents_, web_contents_->GetPrimaryMainFrame(),
+      content::JAVASCRIPT_DIALOG_TYPE_ALERT, std::u16string(), std::u16string(),
+      callback_helper.GetCallback(), &did_suppress);
   ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
 
   prerender_helper_.WaitForPrerenderLoadCompletion(prerender_url);
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc
index 65b5ca77..a73e710b 100644
--- a/chrome/browser/ui/login/login_handler_browsertest.cc
+++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -1749,7 +1749,7 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), broken_ssl_page));
     ASSERT_EQ("127.0.0.1", contents->GetLastCommittedURL().host());
     ASSERT_TRUE(contents->GetLastCommittedURL().SchemeIs("https"));
-    ASSERT_TRUE(WaitForRenderFrameReady(contents->GetMainFrame()));
+    ASSERT_TRUE(WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
   }
 
   // An overrideable SSL interstitial is now being displayed. Navigate to the
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
index 8f5ba60..81efd4c 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
@@ -102,7 +102,7 @@
   if (auto* service =
           AboutThisSiteServiceFactory::GetForProfile(GetProfile())) {
     return service->GetAboutThisSiteInfo(
-        site_url_, web_contents_->GetMainFrame()->GetPageUkmSourceId());
+        site_url_, web_contents_->GetPrimaryMainFrame()->GetPageUkmSourceId());
   }
   return absl::nullopt;
 }
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 47ec52e..18e3a4cb 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -1215,7 +1215,7 @@
 
   content_settings::PageSpecificContentSettings* pscs =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents()->GetMainFrame());
+          web_contents()->GetPrimaryMainFrame());
   EXPECT_FALSE(pscs->HasAccessedTopics());
   EXPECT_THAT(pscs->GetAccessedTopics(), testing::IsEmpty());
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 65140927..38ffc285 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -295,7 +295,7 @@
       this, leak_type, url, username,
       std::make_unique<
           password_manager::metrics_util::LeakDialogMetricsRecorder>(
-          web_contents()->GetMainFrame()->GetPageUkmSourceId(),
+          web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
           password_manager::GetLeakDialogType(leak_type)));
   dialog_controller_.reset(raw_controller);
   raw_controller->ShowCredentialLeakPrompt(
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
index 951c1a1..825a94a 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
@@ -49,11 +49,11 @@
                 FormData()),
             password_manager::ContentPasswordManagerDriverFactory::
                 FromWebContents(web_contents)
-                    ->GetDriverForFrame(web_contents->GetMainFrame())
+                    ->GetDriverForFrame(web_contents->GetPrimaryMainFrame())
                     ->AsWeakPtr(),
             nullptr /* PasswordGenerationPopupObserver*/,
             web_contents,
-            web_contents->GetMainFrame()) {}
+            web_contents->GetPrimaryMainFrame()) {}
 
   ~TestPasswordGenerationPopupController() override {}
 
diff --git a/chrome/browser/ui/passwords/ui_utils.cc b/chrome/browser/ui/passwords/ui_utils.cc
index 93726505..bf0f48c4 100644
--- a/chrome/browser/ui/passwords/ui_utils.cc
+++ b/chrome/browser/ui/passwords/ui_utils.cc
@@ -250,7 +250,7 @@
 
 mojo::Remote<network::mojom::URLLoaderFactory> GetURLLoaderForMainFrame(
     content::WebContents* web_contents) {
-  content::RenderFrameHost* frame = web_contents->GetMainFrame();
+  content::RenderFrameHost* frame = web_contents->GetPrimaryMainFrame();
   mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory;
   frame->CreateNetworkServiceDefaultFactory(
       url_loader_factory.BindNewPipeAndPassReceiver());
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
index bf98067..5fe4a850 100644
--- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
+++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
@@ -80,8 +80,9 @@
     WellKnownChangePasswordNavigationThrottle(NavigationHandle* handle)
     : NavigationThrottle(handle),
       request_url_(handle->GetURL()),
-      source_id_(
-          handle->GetWebContents()->GetMainFrame()->GetPageUkmSourceId()) {
+      source_id_(handle->GetWebContents()
+                     ->GetPrimaryMainFrame()
+                     ->GetPageUkmSourceId()) {
   // If this is a prerender navigation, we're only constructing the throttle
   // so it can cancel the prerender.
   if (handle->IsInPrerenderedMainFrame())
diff --git a/chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.cc b/chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.cc
index 118c57c2..9c84e90 100644
--- a/chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.cc
+++ b/chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.cc
@@ -29,7 +29,7 @@
 
 content::RenderFrameHost* ChromePDFWebContentsHelperClient::FindPdfFrame(
     content::WebContents* contents) {
-  content::RenderFrameHost* main_frame = contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = contents->GetPrimaryMainFrame();
   content::RenderFrameHost* pdf_frame =
       pdf_frame_util::FindPdfChildFrame(main_frame);
   return pdf_frame ? pdf_frame : main_frame;
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc
index c70cc68..6c74ce14 100644
--- a/chrome/browser/ui/popup_browsertest.cc
+++ b/chrome/browser/ui/popup_browsertest.cc
@@ -67,7 +67,7 @@
     Browser* popup = ui_test_utils::WaitForBrowserToOpen();
     EXPECT_NE(popup, browser);
     auto* popup_contents = popup->tab_strip_model()->GetActiveWebContents();
-    EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetMainFrame()));
+    EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetPrimaryMainFrame()));
     return popup;
   }
 };
diff --git a/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc b/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc
index 84d8fa34..cddc577eb 100644
--- a/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc
+++ b/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc
@@ -233,7 +233,7 @@
       https_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
   EXPECT_FALSE(core_tab_helper->new_tab_start_time().is_null());
   histogram_tester.ExpectTotalCount("Tab.NewTabOnload.Other", 1);
@@ -251,7 +251,7 @@
 
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), ntp_url);
+          web_contents()->GetPrimaryMainFrame(), ntp_url);
   EXPECT_NE(nullptr, fenced_frame_host);
   // Fenced frames should not update the title of the web contents.
   EXPECT_EQ(u"Title Of Awesomeness", web_contents()->GetTitle());
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index 208ac32..9bff2c22 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -91,7 +91,7 @@
     return false;
 
   return instant_service->IsInstantProcess(
-      contents->GetMainFrame()->GetProcess()->GetID());
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID());
 }
 
 // Called when an NTP finishes loading. If the load start time was noted,
diff --git a/chrome/browser/ui/search/third_party_ntp_browsertest.cc b/chrome/browser/ui/search/third_party_ntp_browsertest.cc
index 8929045..a6e82a4 100644
--- a/chrome/browser/ui/search/third_party_ntp_browsertest.cc
+++ b/chrome/browser/ui/search/third_party_ntp_browsertest.cc
@@ -58,7 +58,7 @@
   InstantService* instant_service =
       InstantServiceFactory::GetForProfile(browser()->profile());
   EXPECT_TRUE(instant_service->IsInstantProcess(
-      contents->GetMainFrame()->GetProcess()->GetID()));
+      contents->GetPrimaryMainFrame()->GetProcess()->GetID()));
 
   // Add a chrome-search://most-visited/title.html?rid=1&fs=0 subframe and
   // verify that navigation completes successfully, with no kills.
@@ -124,8 +124,8 @@
   }
 
   // Verify that |tab1| and |tab2| share a process.
-  EXPECT_EQ(tab1->GetMainFrame()->GetProcess(),
-            tab2->GetMainFrame()->GetProcess());
+  EXPECT_EQ(tab1->GetPrimaryMainFrame()->GetProcess(),
+            tab2->GetPrimaryMainFrame()->GetProcess());
 }
 
 // Verify that a third-party NTP commits in a remote NTP SiteInstance.
@@ -145,6 +145,7 @@
   EXPECT_EQ(ntp_url, content::EvalJs(web_contents, "window.location.href"));
 
   // Verify that NTP committed in remote NTP SiteInstance.
-  EXPECT_EQ(GURL("chrome-search://remote-ntp/"),
-            web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+  EXPECT_EQ(
+      GURL("chrome-search://remote-ntp/"),
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
 }
diff --git a/chrome/browser/ui/search/third_party_ntp_uitest.cc b/chrome/browser/ui/search/third_party_ntp_uitest.cc
index 20d6af8..67e571f6 100644
--- a/chrome/browser/ui/search/third_party_ntp_uitest.cc
+++ b/chrome/browser/ui/search/third_party_ntp_uitest.cc
@@ -77,7 +77,7 @@
     ASSERT_TRUE(content::ExecJs(tab1, "window.location.reload()"));
     nav_observer.WaitForNavigationFinished();
     ASSERT_TRUE(nav_observer.last_navigation_succeeded());
-    EXPECT_EQ(ntp_url, tab1->GetMainFrame()->GetLastCommittedURL());
+    EXPECT_EQ(ntp_url, tab1->GetPrimaryMainFrame()->GetLastCommittedURL());
     EXPECT_EQ(1, content::EvalJs(tab1, "history.length"));
   }
   // Verify that the omnibox retained its focus.
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
index 95b23557..812d4aa5 100644
--- a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
+++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
@@ -116,7 +116,7 @@
 
   // Only accept messages from the main frame.
   if (osdd_handler_receivers_.GetCurrentTargetFrame() !=
-      web_contents()->GetMainFrame())
+      web_contents()->GetPrimaryMainFrame())
     return;
 
   // Make sure that the page is the current page and other basic checks.
@@ -150,7 +150,7 @@
   if (keyword.empty())
     return;
 
-  auto* frame = web_contents()->GetMainFrame();
+  auto* frame = web_contents()->GetPrimaryMainFrame();
   mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory;
   frame->CreateNetworkServiceDefaultFactory(
       url_loader_factory.BindNewPipeAndPassReceiver());
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper_browsertest.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper_browsertest.cc
index d077f8e..d467f4b7 100644
--- a/chrome/browser/ui/search_engines/search_engine_tab_helper_browsertest.cc
+++ b/chrome/browser/ui/search_engines/search_engine_tab_helper_browsertest.cc
@@ -243,7 +243,7 @@
   EXPECT_FALSE(host_observer.was_activated());
   // Submits a search query.
   content::TestNavigationObserver observer(GetWebContents());
-  EXPECT_EQ(nullptr, content::EvalJs(GetWebContents()->GetMainFrame(),
+  EXPECT_EQ(nullptr, content::EvalJs(GetWebContents()->GetPrimaryMainFrame(),
                                      "submit_form();"));
   observer.Wait();
 
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
index 5febbc7da..8755869 100644
--- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
+++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
@@ -38,7 +38,7 @@
       params.url, ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_LINK,
                                                params.transition)};
 
-  web_contents()->GetMainFrame()->NotifyUserActivation(
+  web_contents()->GetPrimaryMainFrame()->NotifyUserActivation(
       blink::mojom::UserActivationNotificationType::kInteraction);
   web_contents()->GetController().LoadURLWithParams(
       content::NavigationController::LoadURLParams(params));
diff --git a/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc b/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc
index c4c8a61..3c801e8 100644
--- a/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc
+++ b/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc
@@ -443,7 +443,7 @@
       SyncEncryptionKeysTabHelper::FromWebContents(target_contents);
   ASSERT_NE(encryption_keys_tab_helper, nullptr);
   EXPECT_TRUE(encryption_keys_tab_helper->HasEncryptionKeysApiForTesting(
-      target_contents->GetMainFrame()));
+      target_contents->GetPrimaryMainFrame()));
 
   // The invocation of the API, even with dummy values, should propagate until
   // TrustedVaultClient and its observers.
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
index 2f473aa..3c07d96 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
@@ -123,7 +123,7 @@
 
   std::string login_complete_message =
       "chrome.send('lstFetchResults', [" + json_string + "]);";
-  content::RenderFrameHost* root = web_contents()->GetMainFrame();
+  content::RenderFrameHost* root = web_contents()->GetPrimaryMainFrame();
   content::ExecuteScriptAsync(root, login_complete_message);
   WaitForSigninCompleteMessage();
 }
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc
index a0dbaaa..74e0ee7 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.cc
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -316,7 +316,7 @@
 void CoreTabHelper::OnVisibilityChanged(content::Visibility visibility) {
   if (visibility == content::Visibility::VISIBLE) {
     web_cache::WebCacheManager::GetInstance()->ObserveActivity(
-        web_contents()->GetMainFrame()->GetProcess()->GetID());
+        web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID());
   }
 }
 
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc
index f9e99d86..6cc3649 100644
--- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc
+++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc
@@ -88,7 +88,7 @@
   }
 
   content::GlobalRenderFrameHostId GetGlobalId(int tab) {
-    auto* const main_frame = GetWebContents(tab)->GetMainFrame();
+    auto* const main_frame = GetWebContents(tab)->GetPrimaryMainFrame();
     return main_frame ? main_frame->GetGlobalId()
                       : content::GlobalRenderFrameHostId();
   }
@@ -97,7 +97,9 @@
     return l10n_util::GetStringFUTF16(
         IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
         url_formatter::FormatOriginForSecurityDisplay(
-            GetWebContents(tab)->GetMainFrame()->GetLastCommittedOrigin(),
+            GetWebContents(tab)
+                ->GetPrimaryMainFrame()
+                ->GetLastCommittedOrigin(),
             url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS));
   }
 
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 5cabdaa..29799453 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -1958,7 +1958,7 @@
       if (ShouldRunUnloadListenerBeforeClosing(contents))
         continue;
       content::RenderProcessHost* process =
-          contents->GetMainFrame()->GetProcess();
+          contents->GetPrimaryMainFrame()->GetProcess();
       ++processes[process];
     }
 
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
index f3efc44..62a6ec4 100644
--- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -384,10 +384,10 @@
   std::unique_ptr<WebContents> CreateWebContentsWithSharedRPH(
       WebContents* web_contents) {
     WebContents::CreateParams create_params(
-        profile(), web_contents->GetMainFrame()->GetSiteInstance());
+        profile(), web_contents->GetPrimaryMainFrame()->GetSiteInstance());
     std::unique_ptr<WebContents> retval = WebContents::Create(create_params);
-    EXPECT_EQ(retval->GetMainFrame()->GetProcess(),
-              web_contents->GetMainFrame()->GetProcess());
+    EXPECT_EQ(retval->GetPrimaryMainFrame()->GetProcess(),
+              web_contents->GetPrimaryMainFrame()->GetProcess());
     return retval;
   }
 
@@ -2270,8 +2270,9 @@
     tabstrip.CloseAllTabs();
     // On a mock RPH this checks whether we *attempted* fast shutdown.
     // A real RPH would reject our attempt since there is an unload handler.
-    EXPECT_TRUE(
-        raw_contents1->GetMainFrame()->GetProcess()->FastShutdownStarted());
+    EXPECT_TRUE(raw_contents1->GetPrimaryMainFrame()
+                    ->GetProcess()
+                    ->FastShutdownStarted());
     EXPECT_EQ(2, tabstrip.count());
 
     delegate.set_run_unload_listener(false);
@@ -2294,8 +2295,9 @@
     tabstrip.AppendWebContents(std::move(contents2), true);
 
     tabstrip.CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
-    EXPECT_FALSE(
-        raw_contents1->GetMainFrame()->GetProcess()->FastShutdownStarted());
+    EXPECT_FALSE(raw_contents1->GetPrimaryMainFrame()
+                     ->GetProcess()
+                     ->FastShutdownStarted());
     EXPECT_EQ(1, tabstrip.count());
 
     tabstrip.CloseAllTabs();
diff --git a/chrome/browser/ui/thumbnails/background_thumbnail_video_capturer.cc b/chrome/browser/ui/thumbnails/background_thumbnail_video_capturer.cc
index 4a48231..fe28fa6 100644
--- a/chrome/browser/ui/thumbnails/background_thumbnail_video_capturer.cc
+++ b/chrome/browser/ui/thumbnails/background_thumbnail_video_capturer.cc
@@ -40,7 +40,10 @@
     return;
 
   content::RenderWidgetHostView* const source_view =
-      contents_->GetMainFrame()->GetRenderViewHost()->GetWidget()->GetView();
+      contents_->GetPrimaryMainFrame()
+          ->GetRenderViewHost()
+          ->GetWidget()
+          ->GetView();
   if (!source_view)
     return;
 
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
index 20467cc..f382273 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
@@ -94,7 +94,7 @@
   // none.
   content::RenderWidgetHostView* GetView() {
     auto* const contents = web_contents();
-    return contents ? contents->GetMainFrame()
+    return contents ? contents->GetPrimaryMainFrame()
                           ->GetRenderViewHost()
                           ->GetWidget()
                           ->GetView()
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc
index ded64c6..023acb637 100644
--- a/chrome/browser/ui/unload_controller.cc
+++ b/chrome/browser/ui/unload_controller.cc
@@ -327,7 +327,7 @@
         *(tabs_needing_before_unload_fired_.begin());
     // Null check render_view_host here as this gets called on a PostTask and
     // the tab's render_view_host may have been nulled out.
-    if (web_contents->GetMainFrame()->GetRenderViewHost()) {
+    if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost()) {
       // If there's a devtools window attached to |web_contents|,
       // we would like devtools to call its own beforeunload handlers first,
       // and then call beforeunload handlers for |web_contents|.
@@ -359,7 +359,7 @@
     content::WebContents* web_contents = *(tabs_needing_unload_fired_.begin());
     // Null check render_view_host here as this gets called on a PostTask and
     // the tab's render_view_host may have been nulled out.
-    if (web_contents->GetMainFrame()->GetRenderViewHost()) {
+    if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost()) {
       web_contents->ClosePage();
     } else {
       ClearUnloadState(web_contents, true);
diff --git a/chrome/browser/ui/views/autofill/payments/credit_card_access_manager_browsertest.cc b/chrome/browser/ui/views/autofill/payments/credit_card_access_manager_browsertest.cc
index 7c9fb40..8c0046f 100644
--- a/chrome/browser/ui/views/autofill/payments/credit_card_access_manager_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/credit_card_access_manager_browsertest.cc
@@ -40,7 +40,7 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     ContentAutofillDriver* autofill_driver =
         ContentAutofillDriverFactory::FromWebContents(web_contents)
-            ->DriverForFrame(web_contents->GetMainFrame());
+            ->DriverForFrame(web_contents->GetPrimaryMainFrame());
     return autofill_driver->autofill_manager()->GetCreditCardAccessManager();
   }
 
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
index 5d0efe7f..0239187 100644
--- a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
@@ -190,7 +190,7 @@
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             &test_url_loader_factory_);
     ContentAutofillDriver::GetForRenderFrameHost(
-        GetActiveWebContents()->GetMainFrame())
+        GetActiveWebContents()->GetPrimaryMainFrame())
         ->autofill_manager()
         ->client()
         ->GetPaymentsClient()
@@ -199,7 +199,7 @@
     // Set up this class as the ObserverForTest implementation.
     local_card_migration_manager_ =
         ContentAutofillDriver::GetForRenderFrameHost(
-            GetActiveWebContents()->GetMainFrame())
+            GetActiveWebContents()->GetPrimaryMainFrame())
             ->autofill_manager()
             ->client()
             ->GetFormDataImporter()
diff --git a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_test_base.cc b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_test_base.cc
index 78a186e7..bcd99fb4 100644
--- a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_test_base.cc
+++ b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_test_base.cc
@@ -226,7 +226,7 @@
 
 AutofillOfferManager* OfferNotificationBubbleViewsTestBase::GetOfferManager() {
   return ContentAutofillDriver::GetForRenderFrameHost(
-             GetActiveWebContents()->GetMainFrame())
+             GetActiveWebContents()->GetPrimaryMainFrame())
       ->autofill_manager()
       ->GetOfferManager();
 }
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
index 42e95fa..36a31aa 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -192,7 +192,7 @@
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             &test_url_loader_factory_);
     ContentAutofillDriver::GetForRenderFrameHost(
-        GetActiveWebContents()->GetMainFrame())
+        GetActiveWebContents()->GetPrimaryMainFrame())
         ->autofill_manager()
         ->client()
         ->GetPaymentsClient()
@@ -203,19 +203,20 @@
     WaitForPersonalDataManagerToBeLoaded(GetProfile(0));
 
     // Set up this class as the ObserverForTest implementation.
-    credit_card_save_manager_ = ContentAutofillDriver::GetForRenderFrameHost(
-                                    GetActiveWebContents()->GetMainFrame())
-                                    ->autofill_manager()
-                                    ->client()
-                                    ->GetFormDataImporter()
-                                    ->credit_card_save_manager_.get();
+    credit_card_save_manager_ =
+        ContentAutofillDriver::GetForRenderFrameHost(
+            GetActiveWebContents()->GetPrimaryMainFrame())
+            ->autofill_manager()
+            ->client()
+            ->GetFormDataImporter()
+            ->credit_card_save_manager_.get();
     credit_card_save_manager_->SetEventObserverForTesting(this);
     AddEventObserverToController();
 
     // Set up this class as the ObserverForTest implementation.
     AutofillManager* autofill_manager =
         ContentAutofillDriver::GetForRenderFrameHost(
-            GetActiveWebContents()->GetMainFrame())
+            GetActiveWebContents()->GetPrimaryMainFrame())
             ->autofill_manager();
     autofill_manager->AddObserver(this);
 
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index cd16c9c6..445eaa15 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -472,10 +472,10 @@
   allowed_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
   // This captures a snapshot of the allowed cookies of the current page so we
-  // are fine using WebContents::GetMainFrame() here
+  // are fine using WebContents::GetPrimaryMainFrame() here
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents_->GetMainFrame());
+          web_contents_->GetPrimaryMainFrame());
   allowed_cookies_tree_model_ =
       CreateCookiesTreeModel(content_settings->allowed_local_shared_objects());
   std::unique_ptr<CookiesTreeViewDrawingProvider> allowed_drawing_provider =
@@ -519,7 +519,7 @@
 
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents_->GetMainFrame());
+          web_contents_->GetPrimaryMainFrame());
   blocked_cookies_tree_model_ =
       CreateCookiesTreeModel(content_settings->blocked_local_shared_objects());
   std::unique_ptr<CookiesTreeViewDrawingProvider> blocked_drawing_provider =
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
index 3c204e8..e1ee11b 100644
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -156,9 +156,9 @@
       // list of all available tabs.
       const bool current_tab_selected =
           web_contents &&
-          web_contents->GetMainFrame()->GetProcess()->GetID() ==
+          web_contents->GetPrimaryMainFrame()->GetProcess()->GetID() ==
               selected_media.web_contents_id.render_process_id &&
-          web_contents->GetMainFrame()->GetRoutingID() ==
+          web_contents->GetPrimaryMainFrame()->GetRoutingID() ==
               selected_media.web_contents_id.main_render_frame_id;
 
       if (dialog_type == DialogType::kPreferCurrentTab) {
diff --git a/chrome/browser/ui/views/device_chooser_browsertest.cc b/chrome/browser/ui/views/device_chooser_browsertest.cc
index 0e81f820..5e5ae69 100644
--- a/chrome/browser/ui/views/device_chooser_browsertest.cc
+++ b/chrome/browser/ui/views/device_chooser_browsertest.cc
@@ -22,7 +22,7 @@
     Browser* browser,
     std::unique_ptr<permissions::ChooserController> controller) {
   auto* contents = browser->tab_strip_model()->GetActiveWebContents();
-  chrome::ShowDeviceChooserDialog(contents->GetMainFrame(),
+  chrome::ShowDeviceChooserDialog(contents->GetPrimaryMainFrame(),
                                   std::move(controller));
 }
 
diff --git a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
index 6f5bb35..a9b278c7 100644
--- a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
+++ b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
@@ -1024,7 +1024,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content::NavigationController& controller = web_contents->GetController();
   int initial_history_count = controller.GetEntryCount();
-  GURL initial_url = web_contents->GetMainFrame()->GetLastCommittedURL();
+  GURL initial_url = web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
   // Focus the omnibox.
@@ -1049,10 +1049,11 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content::TestNavigationObserver(new_web_contents, 1).Wait();
   EXPECT_EQ(dragged_url,
-            new_web_contents->GetMainFrame()->GetLastCommittedURL());
+            new_web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   // Verify that the initial tab didn't navigate.
-  EXPECT_EQ(initial_url, web_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(initial_url,
+            web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_history_count, controller.GetEntryCount());
 
   // Verify that the focus moved from the omnibox to the tab contents.
@@ -1068,7 +1069,7 @@
   ASSERT_TRUE(NavigateRightFrame(frame_site, "title1.html"));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  GURL initial_url = web_contents->GetMainFrame()->GetLastCommittedURL();
+  GURL initial_url = web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
   // Focus the omnibox.
@@ -1129,7 +1130,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content::NavigationController& controller = web_contents->GetController();
   int initial_history_count = controller.GetEntryCount();
-  GURL initial_url = web_contents->GetMainFrame()->GetLastCommittedURL();
+  GURL initial_url = web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
   // Focus the omnibox.
@@ -1155,10 +1156,11 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content::TestNavigationObserver(new_web_contents, 1).Wait();
   EXPECT_EQ(net::FilePathToFileURL(dragged_file),
-            new_web_contents->GetMainFrame()->GetLastCommittedURL());
+            new_web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 
   // Verify that the initial tab didn't navigate.
-  EXPECT_EQ(initial_url, web_contents->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_EQ(initial_url,
+            web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_history_count, controller.GetEntryCount());
 
   // Verify that the focus moved from the omnibox to the tab contents.
@@ -1197,7 +1199,8 @@
   EXPECT_EQ(123, content::EvalJs(GetRightFrame(), "123"));
 
   // Verify that the history remains unchanged.
-  EXPECT_NE(dragged_url, web_contents()->GetMainFrame()->GetLastCommittedURL());
+  EXPECT_NE(dragged_url,
+            web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
   EXPECT_EQ(initial_history_count, controller.GetEntryCount());
 }
 
@@ -1621,7 +1624,7 @@
     DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState* state) {
   // Delete the left frame in an attempt to repro https://crbug.com/670123.
   content::RenderFrameDeletedObserver frame_deleted_observer(GetLeftFrame());
-  ASSERT_TRUE(ExecuteScript(web_contents()->GetMainFrame(),
+  ASSERT_TRUE(ExecuteScript(web_contents()->GetPrimaryMainFrame(),
                             "frame = document.getElementById('left');\n"
                             "frame.parentNode.removeChild(frame);\n"));
   frame_deleted_observer.WaitUntilDeleted();
@@ -2132,10 +2135,12 @@
   ui_test_utils::TabAddedWaiter wait_for_new_tab(browser());
 
   // Create a new tab that closes itself on dragover event.
-  ASSERT_TRUE(ExecuteScript(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      "window.open('javascript:document.addEventListener("
-      "\"dragover\", () => {window.close(); })');"));
+  ASSERT_TRUE(ExecuteScript(browser()
+                                ->tab_strip_model()
+                                ->GetActiveWebContents()
+                                ->GetPrimaryMainFrame(),
+                            "window.open('javascript:document.addEventListener("
+                            "\"dragover\", () => {window.close(); })');"));
 
   wait_for_new_tab.Wait();
 
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
index 4933a74..2712303 100644
--- a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
@@ -117,8 +117,8 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   std::unique_ptr<permissions::ChooserController> chooser_controller(
-      new DevicePermissionsDialogController(web_contents()->GetMainFrame(),
-                                            prompt()));
+      new DevicePermissionsDialogController(
+          web_contents()->GetPrimaryMainFrame(), prompt()));
 
   constrained_window::ShowWebModalDialogViews(
       new ChooserDialogView(std::move(chooser_controller)), web_contents());
diff --git a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
index 83cd9993..5ad894d 100644
--- a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
@@ -102,7 +102,7 @@
     dialog_ = new ExternalProtocolDialog(
         web_contents, GURL("telnet://12345"), u"/usr/bin/telnet",
         url::Origin::Create(GURL(initiating_origin)),
-        web_contents->GetMainFrame()->GetWeakDocumentPtr());
+        web_contents->GetPrimaryMainFrame()->GetWeakDocumentPtr());
   }
 
   void SetChecked(bool checked) {
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_browsertest.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_browsertest.cc
index e219d81..a84f8d6 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_browsertest.cc
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_browsertest.cc
@@ -34,8 +34,10 @@
   // UiBrowserTest:
   void ShowUi(const std::string& name) override {
 #if BUILDFLAG(IS_WIN)
-    content::RenderFrameHost* parent_frame =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* parent_frame = browser()
+                                                 ->tab_strip_model()
+                                                 ->GetActiveWebContents()
+                                                 ->GetPrimaryMainFrame();
     eye_dropper_ = ShowEyeDropper(parent_frame, /*listener=*/nullptr);
 #endif
   }
diff --git a/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc b/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc
index e331c9e..f2016bab 100644
--- a/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc
+++ b/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc
@@ -563,7 +563,8 @@
       ChildFrameAt(third_party_web_contents, 0);
   ASSERT_TRUE(third_party_iframe);
   ASSERT_EQ(third_party_iframe->GetLastCommittedOrigin(),
-            first_party_web_contents->GetMainFrame()->GetLastCommittedOrigin());
+            first_party_web_contents->GetPrimaryMainFrame()
+                ->GetLastCommittedOrigin());
 
   // 3. Also showing https://b.com/title1.html
   Browser* third_window = CreateBrowser(profile);
@@ -706,7 +707,8 @@
       ChildFrameAt(third_party_web_contents, 0);
   ASSERT_TRUE(third_party_iframe);
   ASSERT_EQ(third_party_iframe->GetLastCommittedOrigin(),
-            first_party_web_contents->GetMainFrame()->GetLastCommittedOrigin());
+            first_party_web_contents->GetPrimaryMainFrame()
+                ->GetLastCommittedOrigin());
 
   // The b.com iframe inside a.com should wait to receive a handle from a
   // top-level b.com page.
@@ -1011,7 +1013,7 @@
   // Load a fenced frame.
   GURL fenced_frame_url = https_server().GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_host =
-      CreateFencedFrame(web_contents->GetMainFrame(), fenced_frame_url);
+      CreateFencedFrame(web_contents->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
   // File system access is disabled for fenced frames.
diff --git a/chrome/browser/ui/views/file_system_access/file_system_access_icon_view.cc b/chrome/browser/ui/views/file_system_access/file_system_access_icon_view.cc
index b2da00d..75cb4e20 100644
--- a/chrome/browser/ui/views/file_system_access/file_system_access_icon_view.cc
+++ b/chrome/browser/ui/views/file_system_access/file_system_access_icon_view.cc
@@ -40,7 +40,7 @@
     has_write_access_ = false;
   } else {
     url::Origin origin =
-        GetWebContents()->GetMainFrame()->GetLastCommittedOrigin();
+        GetWebContents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
     auto* context =
         FileSystemAccessPermissionContextFactory::GetForProfileIfExists(
             GetWebContents()->GetBrowserContext());
@@ -70,7 +70,8 @@
 
 void FileSystemAccessIconView::OnExecuting(ExecuteSource execute_source) {
   auto* web_contents = GetWebContents();
-  url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  url::Origin origin =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
 
   auto* context =
       FileSystemAccessPermissionContextFactory::GetForProfileIfExists(
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index 8a1a0b0..96fc10b 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -160,7 +160,7 @@
   // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom".
   contents->ClearFocusedElement();
   NativeWebKeyboardEvent event(key_event);
-  contents->GetMainFrame()
+  contents->GetPrimaryMainFrame()
       ->GetRenderViewHost()
       ->GetWidget()
       ->ForwardKeyboardEventWithLatencyInfo(event, *key_event.latency());
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index 17c3d98..80bfd374 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -197,7 +197,7 @@
   EXPECT_GT(GetAppFrameView()->GetTopInset(false), 0);
 
   static_cast<content::WebContentsDelegate*>(app_browser_)
-      ->EnterFullscreenModeForTab(web_contents_->GetMainFrame(), {});
+      ->EnterFullscreenModeForTab(web_contents_->GetPrimaryMainFrame(), {});
 
   EXPECT_EQ(GetAppFrameView()->GetTopInset(false), 0);
 }
@@ -211,7 +211,7 @@
       ui_test_utils::NavigateToURL(app_browser_, GURL("http://example.com")));
 
   static_cast<content::WebContentsDelegate*>(app_browser_)
-      ->EnterFullscreenModeForTab(web_contents_->GetMainFrame(), {});
+      ->EnterFullscreenModeForTab(web_contents_->GetPrimaryMainFrame(), {});
 
   EXPECT_TRUE(app_browser_view_->toolbar()->custom_tab_bar()->IsDrawn());
 }
@@ -322,7 +322,7 @@
  public:
   explicit SaveCardOfferObserver(content::WebContents* web_contents) {
     manager_ = autofill::ContentAutofillDriver::GetForRenderFrameHost(
-                   web_contents->GetMainFrame())
+                   web_contents->GetPrimaryMainFrame())
                    ->autofill_manager()
                    ->client()
                    ->GetFormDataImporter()
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
index 1dc3986f..1feed36 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -753,8 +753,9 @@
   }
 
   ContentSettingImageView* GrantGeolocationPermission() {
-    content::RenderFrameHost* frame =
-        app_browser_->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    content::RenderFrameHost* frame = app_browser_->tab_strip_model()
+                                          ->GetActiveWebContents()
+                                          ->GetPrimaryMainFrame();
     content_settings::PageSpecificContentSettings* content_settings =
         content_settings::PageSpecificContentSettings::GetForFrame(
             frame->GetProcess()->GetID(), frame->GetRoutingID());
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.cc
index dec3173..a2a76871 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.cc
@@ -34,7 +34,7 @@
                                       content::WebContents* web_contents) {
   FullscreenNotificationObserver waiter(browser);
   static_cast<content::WebContentsDelegate*>(browser)
-      ->EnterFullscreenModeForTab(web_contents->GetMainFrame(), {});
+      ->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame(), {});
   waiter.Wait();
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_root_view.cc b/chrome/browser/ui/views/frame/browser_root_view.cc
index b7ca863..ea12b03c 100644
--- a/chrome/browser/ui/views/frame/browser_root_view.cc
+++ b/chrome/browser/ui/views/frame/browser_root_view.cc
@@ -182,7 +182,7 @@
         return;
       }
 
-      content::RenderFrameHost* rfh = web_contents->GetMainFrame();
+      content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
       base::ThreadPool::PostTaskAndReplyWithResult(
           FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
           base::BindOnce(&FindURLMimeType, url),
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
index be53f49a..4bf409d 100644
--- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -124,7 +124,7 @@
       browser()->exclusive_access_manager()->fullscreen_controller();
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  controller->EnterFullscreenModeForTab(web_contents->GetMainFrame());
+  controller->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame());
   EXPECT_TRUE(browser_view->IsFullscreen());
   bool top_view_in_tab_fullscreen =
       browser_view->immersive_mode_controller()->IsEnabled() ? true : false;
@@ -167,7 +167,7 @@
       browser()->exclusive_access_manager()->fullscreen_controller();
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  controller->EnterFullscreenModeForTab(web_contents->GetMainFrame());
+  controller->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame());
   EXPECT_TRUE(browser_view->IsFullscreen());
 
   // The top view should not show up.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
index f0e4944..20e34b1 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
@@ -343,9 +343,11 @@
   EXPECT_TRUE(test_api->manager());
 
   // Add a permission bubble using the test api.
-  test_api->AddSimpleRequest(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      permissions::RequestType::kGeolocation);
+  test_api->AddSimpleRequest(browser()
+                                 ->tab_strip_model()
+                                 ->GetActiveWebContents()
+                                 ->GetPrimaryMainFrame(),
+                             permissions::RequestType::kGeolocation);
 
   // The permission prompt is shown asynchronously. Without immersive mode
   // enabled the anchor should exist.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_unittest.cc
index 11ea1dd4..4846869a 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_unittest.cc
@@ -78,7 +78,8 @@
     FullscreenNotificationObserver waiter(browser());
     auto* delegate = static_cast<content::WebContentsDelegate*>(browser());
     if (tab_fullscreen)
-      delegate->EnterFullscreenModeForTab(web_contents->GetMainFrame(), {});
+      delegate->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame(),
+                                          {});
     else
       delegate->ExitFullscreenModeForTab(web_contents);
     waiter.Wait();
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
index 29c33d6..433ac86 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -267,7 +267,7 @@
     // Make sure the navigation has finished before proceeding.
     url_observer.Wait();
     ASSERT_TRUE(ExecJs(
-        browser_view_->GetActiveWebContents()->GetMainFrame(),
+        browser_view_->GetActiveWebContents()->GetPrimaryMainFrame(),
         "var meta = document.head.appendChild(document.createElement('meta'));"
         "meta.name = 'theme-color';"
         "meta.content = '#123456';"));
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
index 5926761..d20b41c8 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -114,7 +114,7 @@
 void SynchronizeVisualProperties(content::WebContents* contents) {
   DCHECK(contents);
 
-  content::RenderFrameHost* main_frame = contents->GetMainFrame();
+  content::RenderFrameHost* main_frame = contents->GetPrimaryMainFrame();
   if (!main_frame)
     return;
 
@@ -210,7 +210,7 @@
                    const GURL& validated_url,
                    int error_code) override {
     if (render_frame_host->IsActive() &&
-        (render_frame_host == web_contents()->GetMainFrame())) {
+        (render_frame_host == web_contents()->GetPrimaryMainFrame())) {
       UpdateBrowserControlsStateShown(/*animate=*/true);
     }
   }
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
index 1cc62b4..40aa1c4 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -1400,7 +1400,7 @@
   auto* permission_manager =
       permissions::PermissionRequestManager::FromWebContents(active_contents);
   TopControlsShownRatioWaiter waiter(top_controls_slide_controller());
-  permission_manager->AddRequest(active_contents->GetMainFrame(),
+  permission_manager->AddRequest(active_contents->GetPrimaryMainFrame(),
                                  &permission_request);
   waiter.WaitForRatio(1.f);
   EXPECT_FLOAT_EQ(top_controls_slide_controller()->GetShownRatio(), 1.f);
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
index 8d1602c..be004a0e 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
@@ -122,8 +122,8 @@
   void EnterActiveTabFullscreen() {
     FullscreenNotificationObserver fullscreen_observer(browser());
     auto* delegate = static_cast<content::WebContentsDelegate*>(browser());
-    delegate->EnterFullscreenModeForTab(GetActiveWebContents()->GetMainFrame(),
-                                        {});
+    delegate->EnterFullscreenModeForTab(
+        GetActiveWebContents()->GetPrimaryMainFrame(), {});
     fullscreen_observer.Wait();
     ASSERT_TRUE(delegate->IsFullscreenForTabOrPending(GetActiveWebContents()));
   }
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
index 62d2701..e75c44e 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
@@ -406,7 +406,7 @@
   void StartPlayback() {
     // The test HTML files used in these tests contain "play()" functions that
     // play the video.
-    GetActiveWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    GetActiveWebContents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"play()", base::NullCallback());
   }
 
@@ -425,12 +425,12 @@
   }
 
   void DisablePictureInPicture() {
-    GetActiveWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    GetActiveWebContents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"disablePictureInPicture()", base::NullCallback());
   }
 
   void EnablePictureInPicture() {
-    GetActiveWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    GetActiveWebContents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         u"enablePictureInPicture()", base::NullCallback());
   }
 
@@ -1117,8 +1117,8 @@
     MediaDialogViewBrowserTest::SetUpOnMainThread();
   }
 
-  content::RenderFrameHost* GetMainFrame() {
-    return GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame() {
+    return GetActiveWebContents()->GetPrimaryMainFrame();
   }
 
  protected:
@@ -1139,7 +1139,7 @@
       "a.test", "/media/session/video-with-metadata.html"));
   GURL url2(embedded_test_server()->GetURL("b.test", "/title1.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
-  content::RenderFrameHost* rfh = GetMainFrame();
+  content::RenderFrameHost* rfh = GetPrimaryMainFrame();
 
   StartPlayback();
   WaitForStart();
@@ -1177,7 +1177,7 @@
       "a.test", "/media/session/video-with-metadata.html"));
   GURL url2(embedded_test_server()->GetURL("b.test", "/title1.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
-  content::RenderFrameHost* rfh = GetMainFrame();
+  content::RenderFrameHost* rfh = GetPrimaryMainFrame();
 
   StartPlayback();
   WaitForStart();
@@ -1227,7 +1227,7 @@
   GURL url3(embedded_test_server()->GetURL(
       "c.test", "/media/session/video-with-metadata.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
-  content::RenderFrameHost* rfh1 = GetMainFrame();
+  content::RenderFrameHost* rfh1 = GetPrimaryMainFrame();
 
   StartPlayback();
   WaitForStart();
@@ -1244,7 +1244,7 @@
             rfh1->GetLifecycleState());
   EXPECT_TRUE(ui_.WaitForToolbarIconHidden());
   EXPECT_FALSE(ui_.IsDialogVisible());
-  content::RenderFrameHost* rfh2 = GetMainFrame();
+  content::RenderFrameHost* rfh2 = GetPrimaryMainFrame();
 
   StartPlayback();
   WaitForStart();
diff --git a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
index 9df64a2..3b659c8 100644
--- a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
+++ b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
@@ -54,7 +54,7 @@
     auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
     HungRendererDialogView::Show(
         web_contents,
-        web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget(),
+        web_contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget(),
         base::DoNothing());
 
     if (name == "MultiplePages") {
@@ -76,7 +76,7 @@
   void EndForWebContents(HungRendererDialogView* dialog,
                          content::WebContents* contents) {
     dialog->EndDialog(
-        contents->GetMainFrame()->GetRenderViewHost()->GetWidget());
+        contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget());
   }
 };
 
@@ -123,7 +123,7 @@
   // showing the window, populate the table model instead.
   dialog->table_model_for_testing()->InitForWebContents(
       web_contents,
-      web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget(),
+      web_contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget(),
       base::DoNothing());
 
   // Makes sure the virtual accessibility views are in sync with the model when
@@ -157,7 +157,7 @@
   content::WebContents* web_contents1 =
       browser1->tab_strip_model()->GetActiveWebContents();
   content::RenderWidgetHost* widget_host1 =
-      web_contents1->GetMainFrame()->GetRenderViewHost()->GetWidget();
+      web_contents1->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
 
   Browser* browser2 =
       Browser::Create(Browser::CreateParams(browser1->profile(), true));
@@ -165,7 +165,7 @@
   content::WebContents* web_contents2 =
       browser2->tab_strip_model()->GetActiveWebContents();
   content::RenderWidgetHost* widget_host2 =
-      web_contents2->GetMainFrame()->GetRenderViewHost()->GetWidget();
+      web_contents2->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget();
 
   EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents1));
   EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2));
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc
index 4f30bb4..61cdd42 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -588,7 +588,7 @@
   const bool show_origin =
       initiating_origin_ &&
       !initiating_origin_->IsSameOriginWith(
-          web_contents()->GetMainFrame()->GetLastCommittedOrigin());
+          web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
   auto leading_content_type = use_grid_view_
                                   ? views::DialogContentType::kText
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
index be7987b2..b88d77b 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
@@ -381,9 +381,12 @@
   const GURL fenced_frame_url = https_server().GetURL(
       GetAppUrlHost(), std::string(GetAppScopePath()) + "index1.html");
   // Create a fenced frame.
-  ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      fenced_frame_url));
+  ASSERT_TRUE(
+      fenced_frame_test_helper().CreateFencedFrame(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetPrimaryMainFrame(),
+                                                   fenced_frame_url));
 
   EXPECT_FALSE(intent_picker_view->GetVisible());
 }
diff --git a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
index ba88d0b1..e578bc5a 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
@@ -121,7 +121,10 @@
           : 0;
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+          browser()
+              ->tab_strip_model()
+              ->GetActiveWebContents()
+              ->GetPrimaryMainFrame());
   content_settings->OnMediaStreamPermissionSet(
       GURL("https://example.com/"), mic_setting | camera_setting, std::string(),
       std::string(), std::string(), std::string());
@@ -133,7 +136,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   content_settings::PageSpecificContentSettings* content_settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents->GetMainFrame());
+          web_contents->GetPrimaryMainFrame());
   switch (content_type) {
     case ContentSettingsType::AUTOMATIC_DOWNLOADS: {
       // Automatic downloads are handled by DownloadRequestLimiter.
@@ -184,7 +187,7 @@
   DCHECK(!notification_permission_request_);
   notification_permission_request_.emplace(
       GURL("https://example.com"), permissions::RequestType::kNotifications);
-  permission_request_manager->AddRequest(web_contents->GetMainFrame(),
+  permission_request_manager->AddRequest(web_contents->GetPrimaryMainFrame(),
                                          &*notification_permission_request_);
   base::RunLoop().RunUntilIdle();
 }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
index 1fd5345..10adf20a 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
@@ -309,7 +309,7 @@
   EXPECT_FALSE(geolocation_icon.GetVisible());
 
   // Query current position, and wait for the query to complete.
-  content::RenderFrameHost* rfh_a = web_contents()->GetMainFrame();
+  content::RenderFrameHost* rfh_a = web_contents()->GetPrimaryMainFrame();
   EXPECT_EQ("received", EvalJs(rfh_a, R"(
       new Promise(resolve => {
         navigator.geolocation.getCurrentPosition(() => resolve('received'));
@@ -324,7 +324,7 @@
   // 2) Navigate away to B.
   EXPECT_TRUE(content::NavigateToURL(web_contents(), url_b));
   EXPECT_TRUE(content::WaitForLoadStop(web_contents()));
-  content::RenderFrameHost* rfh_b = web_contents()->GetMainFrame();
+  content::RenderFrameHost* rfh_b = web_contents()->GetPrimaryMainFrame();
 
   // Geolocation icon should be off after navigation.
   EXPECT_FALSE(geolocation_icon.GetVisible());
@@ -338,7 +338,7 @@
   // BackForwardCache. And |RenderFrameHost| have to be matched with |rfh_a|.
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(content::WaitForLoadStop(web_contents()));
-  EXPECT_EQ(web_contents()->GetMainFrame(), rfh_a);
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame(), rfh_a);
   EXPECT_EQ(rfh_b->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
@@ -349,7 +349,7 @@
   // BackForwardCache. And |RenderFrameHost| have to be matched with |rfh_b|.
   web_contents()->GetController().GoForward();
   EXPECT_TRUE(content::WaitForLoadStop(web_contents()));
-  EXPECT_EQ(web_contents()->GetMainFrame(), rfh_b);
+  EXPECT_EQ(web_contents()->GetPrimaryMainFrame(), rfh_b);
 
   // Geolocation icon should be off.
   EXPECT_FALSE(geolocation_icon.GetVisible());
diff --git a/chrome/browser/ui/views/location_bar/permission_request_chip_browsertest.cc b/chrome/browser/ui/views/location_bar/permission_request_chip_browsertest.cc
index d72398c..b0bda30 100644
--- a/chrome/browser/ui/views/location_bar/permission_request_chip_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/permission_request_chip_browsertest.cc
@@ -35,7 +35,7 @@
 
   EXPECT_NE(nullptr, test_api.manager());
   test_api.AddSimpleRequest(
-      browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+      browser->tab_strip_model()->GetActiveWebContents()->GetPrimaryMainFrame(),
       permissions::RequestType::kGeolocation);
 
   observer.Wait();
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index 5226ef0..118a52c 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -71,7 +71,7 @@
     // notification before testing the zoom bubble visibility.
     FullscreenNotificationObserver waiter(browser());
     static_cast<content::WebContentsDelegate*>(browser())
-        ->EnterFullscreenModeForTab(web_contents->GetMainFrame(), {});
+        ->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame(), {});
     waiter.Wait();
   }
   ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views_browsertest.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views_browsertest.cc
index 1b11f3bc..6f5d74b 100644
--- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views_browsertest.cc
+++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views_browsertest.cc
@@ -36,8 +36,9 @@
 std::unique_ptr<StartPresentationContext> CreateStartPresentationContext(
     content::WebContents* content) {
   return std::make_unique<StartPresentationContext>(
-      content::PresentationRequest(content->GetMainFrame()->GetGlobalId(),
-                                   {GURL(), GURL()}, url::Origin()),
+      content::PresentationRequest(
+          content->GetPrimaryMainFrame()->GetGlobalId(), {GURL(), GURL()},
+          url::Origin()),
       base::DoNothing(), base::DoNothing());
 }
 
diff --git a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
index fe0b3a1..09012ae 100644
--- a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
+++ b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
@@ -111,7 +111,7 @@
   content::ContextMenuParams params;
   params.page_url =
       web_contents->GetController().GetLastCommittedEntry()->GetURL();
-  TestRenderViewContextMenu menu(*web_contents->GetMainFrame(), params);
+  TestRenderViewContextMenu menu(*web_contents->GetPrimaryMainFrame(), params);
   menu.Init();
 
   ASSERT_TRUE(menu.IsItemPresent(IDC_ROUTE_MEDIA));
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
index 3dd9bd5..eb78e27 100644
--- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -425,8 +425,8 @@
   {
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
     content::RenderFrameDeletedObserver crash_observer(
-        web_contents_->GetMainFrame());
-    web_contents_->GetMainFrame()->GetProcess()->Shutdown(1);
+        web_contents_->GetPrimaryMainFrame());
+    web_contents_->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
     crash_observer.WaitUntilDeleted();
   }
   ASSERT_TRUE(web_contents_->IsCrashed());
diff --git a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view_browsertest.cc
index bd35983a..31e4795d4 100644
--- a/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/accuracy_tip_bubble_view_browsertest.cc
@@ -290,9 +290,11 @@
   auto test_api =
       std::make_unique<test::PermissionRequestManagerTestApi>(browser());
   EXPECT_TRUE(test_api->manager());
-  test_api->AddSimpleRequest(
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      permissions::RequestType::kGeolocation);
+  test_api->AddSimpleRequest(browser()
+                                 ->tab_strip_model()
+                                 ->GetActiveWebContents()
+                                 ->GetPrimaryMainFrame(),
+                             permissions::RequestType::kGeolocation);
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(IsUIShowing());
 
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
index e7805cf..fcdf256 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
@@ -67,7 +67,7 @@
 
 void PageInfoBubbleViewBase::RenderFrameDeleted(
     content::RenderFrameHost* render_frame_host) {
-  if (render_frame_host == web_contents()->GetMainFrame()) {
+  if (render_frame_host == web_contents()->GetPrimaryMainFrame()) {
     GetWidget()->Close();
   }
 }
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
index 061baad..fd640df 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -210,7 +210,7 @@
 
   void ExecuteJavaScriptForTests(const std::string& js) {
     base::RunLoop run_loop;
-    web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+    web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         base::ASCIIToUTF16(js),
         base::BindOnce(
             [](base::OnceClosure quit_callback, base::Value result) {
@@ -340,7 +340,7 @@
 IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ViewSourceURL) {
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-  web_contents()->GetMainFrame()->ViewSource();
+  web_contents()->GetPrimaryMainFrame()->ViewSource();
   OpenPageInfoBubble(browser());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_INTERNAL_PAGE,
             PageInfoBubbleView::GetShownBubbleType());
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
index 7f6a4fd..eb224ba 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
@@ -506,7 +506,7 @@
       auto source_id = browser()
                            ->tab_strip_model()
                            ->GetActiveWebContents()
-                           ->GetMainFrame()
+                           ->GetPrimaryMainFrame()
                            ->GetPageUkmSourceId();
       bubble_view->OpenAboutThisSitePage(
           service->GetAboutThisSiteInfo(GetUrl(kAboutThisSiteUrl), source_id)
@@ -562,7 +562,10 @@
     // TODO(crbug.com/1286276): It would be better to actually access the
     // topic through Javascript for an end-to-end test when the API is ready.
     auto* pscs = content_settings::PageSpecificContentSettings::GetForFrame(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
+        browser()
+            ->tab_strip_model()
+            ->GetActiveWebContents()
+            ->GetPrimaryMainFrame());
 
     pscs->OnTopicAccessed(
         url::Origin::Create(GURL("https://a.test")), false,
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
index cb814d5..18017142 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -929,7 +929,7 @@
   std::unique_ptr<content::NavigationSimulator> navigation =
       content::NavigationSimulator::CreateRendererInitiated(
           GURL(kSecureUrl),
-          web_contents_helper_->web_contents()->GetMainFrame());
+          web_contents_helper_->web_contents()->GetPrimaryMainFrame());
   navigation->Start();
   api_->CreateView();
   EXPECT_EQ(kHostname, api_->GetWindowTitle());
@@ -993,7 +993,7 @@
   std::unique_ptr<content::NavigationSimulator> navigation =
       content::NavigationSimulator::CreateRendererInitiated(
           GURL(kSecureUrl),
-          web_contents_helper_->web_contents()->GetMainFrame());
+          web_contents_helper_->web_contents()->GetPrimaryMainFrame());
   navigation->Start();
   api_->CreateView();
 
@@ -1043,7 +1043,7 @@
   std::unique_ptr<content::NavigationSimulator> navigation =
       content::NavigationSimulator::CreateRendererInitiated(
           GURL(kSecureUrl),
-          web_contents_helper_->web_contents()->GetMainFrame());
+          web_contents_helper_->web_contents()->GetPrimaryMainFrame());
   navigation->Start();
   api_->CreateView();
 
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
index 7804482..cec15ed 100644
--- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
@@ -189,7 +189,7 @@
 
 void SafetyTipPageInfoBubbleView::RenderFrameDeleted(
     content::RenderFrameHost* render_frame_host) {
-  if (render_frame_host != web_contents()->GetMainFrame()) {
+  if (render_frame_host != web_contents()->GetPrimaryMainFrame()) {
     return;
   }
 
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
index c546515fd..24ebe3aa 100644
--- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
+++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
@@ -118,7 +118,7 @@
                 base::Unretained(this), base::Unretained(form.get())),
             titles.first, titles.second, form.get(),
             GetURLLoaderForMainFrame(web_contents_).get(),
-            web_contents_->GetMainFrame()->GetLastCommittedOrigin()));
+            web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin()));
     credential_view->SetStoreIndicatorIcon(form->in_store);
     ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get();
     gfx::Insets insets =
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
index 84fd9355..b78454c 100644
--- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
+++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
@@ -49,7 +49,7 @@
           l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE_MD),
           form.username_value, &form,
           GetURLLoaderForMainFrame(web_contents).get(),
-          web_contents->GetMainFrame()->GetLastCommittedOrigin(),
+          web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
           views::style::STYLE_HINT, views::style::STYLE_PRIMARY));
   credential->SetEnabled(false);
 
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc
index 53ec4b5a..7201de7 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -349,11 +349,11 @@
       AddChildView(std::move(destination_dropdown));
 
     const auto titles = GetCredentialLabelsForAccountChooser(password_form);
-    AddChildView(std::make_unique<CredentialsItemView>(
-                     views::Button::PressedCallback(), titles.first,
-                     titles.second, &password_form,
-                     GetURLLoaderForMainFrame(web_contents).get(),
-                     web_contents->GetMainFrame()->GetLastCommittedOrigin()))
+    AddChildView(
+        std::make_unique<CredentialsItemView>(
+            views::Button::PressedCallback(), titles.first, titles.second,
+            &password_form, GetURLLoaderForMainFrame(web_contents).get(),
+            web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin()))
         ->SetEnabled(false);
   } else {
     std::unique_ptr<views::EditableCombobox> username_dropdown =
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc b/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
index 189a3d2..d58c183 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
@@ -167,7 +167,7 @@
   url::Origin kOrigin = url::Origin::Create(kURL);
   ON_CALL(*model_delegate_mock(), GetOrigin).WillByDefault(Return(kOrigin));
   content::NavigationSimulator::NavigateAndCommitFromDocument(
-      kURL, web_contents()->GetMainFrame());
+      kURL, web_contents()->GetPrimaryMainFrame());
 
   // Set the federation_origin to force a Federated Credentials bubble.
   pending_password_.federation_origin = kOrigin;
diff --git a/chrome/browser/ui/views/payments/payment_handler_icon_refetch_browsertest.cc b/chrome/browser/ui/views/payments/payment_handler_icon_refetch_browsertest.cc
index a9cd7a35..bee3dc0 100644
--- a/chrome/browser/ui/views/payments/payment_handler_icon_refetch_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_icon_refetch_browsertest.cc
@@ -48,7 +48,7 @@
     downloader->AddTestServerURL("https://kylepay.com/",
                                  kylepay_server_.GetURL("kylepay.com", "/"));
     ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        GetActiveWebContents()->GetMainFrame())
+        GetActiveWebContents()->GetPrimaryMainFrame())
         ->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
             std::move(downloader));
   }
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
index ee9f353..868e99fd 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -248,8 +248,9 @@
 PaymentHandlerWebFlowViewController::CreateHeaderContentView(
     views::View* header_view) {
   const url::Origin origin =
-      web_contents() ? web_contents()->GetMainFrame()->GetLastCommittedOrigin()
-                     : url::Origin::Create(target_);
+      web_contents()
+          ? web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin()
+          : url::Origin::Create(target_);
   std::unique_ptr<views::Background> background =
       GetHeaderBackground(header_view);
   return std::make_unique<ReadOnlyOriginView>(
@@ -346,8 +347,8 @@
 
   if (first_navigation_complete_callback_) {
     std::move(first_navigation_complete_callback_)
-        .Run(true, web_contents()->GetMainFrame()->GetProcess()->GetID(),
-             web_contents()->GetMainFrame()->GetRoutingID());
+        .Run(true, web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
+             web_contents()->GetPrimaryMainFrame()->GetRoutingID());
   }
 
   UpdateHeaderView();
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
index 07e9fe67..e69db01 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
@@ -60,7 +60,7 @@
     downloader->AddTestServerURL("https://google.com/",
                                  gpay_server_.GetURL("google.com", "/"));
     ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        GetActiveWebContents()->GetMainFrame())
+        GetActiveWebContents()->GetPrimaryMainFrame())
         ->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
             std::move(downloader));
   }
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
index 3890222..0db72c43 100644
--- a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
@@ -138,7 +138,7 @@
     downloader->AddTestServerURL("https://kylepay.com/",
                                  kylepay_.GetURL("kylepay.com", "/"));
     ServiceWorkerPaymentAppFinder::GetOrCreateForCurrentDocument(
-        web_contents->GetMainFrame())
+        web_contents->GetPrimaryMainFrame())
         ->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
             std::move(downloader));
   }
diff --git a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
index daa09d14b..d3691b7 100644
--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
@@ -61,7 +61,8 @@
 
     test_delegate_ =
         std::make_unique<TestSecurePaymentConfirmationPaymentRequestDelegate>(
-            web_contents->GetMainFrame(), model_.GetWeakPtr(), GetWeakPtr());
+            web_contents->GetPrimaryMainFrame(), model_.GetWeakPtr(),
+            GetWeakPtr());
 
     // TODO(crbug.com/1175327): Ideally, we'd expect the browser window to be
     // active here and could check that |IsBrowserWindowActivate()| returned
@@ -119,7 +120,8 @@
 
     test_delegate_ =
         std::make_unique<TestSecurePaymentConfirmationPaymentRequestDelegate>(
-            web_contents->GetMainFrame(), model_.GetWeakPtr(), GetWeakPtr());
+            web_contents->GetPrimaryMainFrame(), model_.GetWeakPtr(),
+            GetWeakPtr());
 
     ResetEventWaiter(DialogEvent::DIALOG_OPENED);
     test_delegate_->ShowDialog(nullptr);
diff --git a/chrome/browser/ui/views/permission_bubble/permission_bubble_interactive_uitest.cc b/chrome/browser/ui/views/permission_bubble/permission_bubble_interactive_uitest.cc
index d4050ac..c14b20a 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_bubble_interactive_uitest.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_bubble_interactive_uitest.cc
@@ -71,9 +71,11 @@
         std::make_unique<test::PermissionRequestManagerTestApi>(browser());
     EXPECT_TRUE(test_api_->manager());
 
-    test_api_->AddSimpleRequest(
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-        permissions::RequestType::kGeolocation);
+    test_api_->AddSimpleRequest(browser()
+                                    ->tab_strip_model()
+                                    ->GetActiveWebContents()
+                                    ->GetPrimaryMainFrame(),
+                                permissions::RequestType::kGeolocation);
 
     EXPECT_TRUE(browser()->window()->IsActive());
 
diff --git a/chrome/browser/ui/views/permission_bubble/permission_chip_interactive_test.cc b/chrome/browser/ui/views/permission_bubble/permission_chip_interactive_test.cc
index d433a42..1aab02c 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_chip_interactive_test.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_chip_interactive_test.cc
@@ -79,7 +79,10 @@
   }
 
   content::RenderFrameHost* GetActiveMainFrame() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
   void RequestPermission(permissions::RequestType type) {
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
index e1ccb53..798313f6 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
@@ -137,7 +137,10 @@
   GURL GetTestUrl() { return GURL("https://example.com"); }
 
   content::RenderFrameHost* GetActiveMainFrame() {
-    return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 
   PermissionChip* GetChip() {
@@ -322,7 +325,7 @@
   content::RenderViewHost* render_view_host = browser()
                                                   ->tab_strip_model()
                                                   ->GetActiveWebContents()
-                                                  ->GetMainFrame()
+                                                  ->GetPrimaryMainFrame()
                                                   ->GetRenderViewHost();
   content::RenderProcessHost* render_process_host =
       render_view_host->GetProcess();
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
index 98c3310c..e3b5531 100644
--- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
+++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
@@ -155,7 +155,8 @@
   content::WebContents* contents = GetWebContents();
   if (!contents || IsDistilledPage(contents->GetLastCommittedURL()))
     return;
-  ukm::SourceId source_id = contents->GetMainFrame()->GetPageUkmSourceId();
+  ukm::SourceId source_id =
+      contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
   ukm::builders::ReaderModeActivated(source_id)
       .SetActivatedViaOmnibox(true)
       .Record(ukm::UkmRecorder::Get());
@@ -171,7 +172,7 @@
 
   if (result.is_last) {
     ukm::SourceId source_id =
-        web_contents->GetMainFrame()->GetPageUkmSourceId();
+        web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();
     ukm::builders::ReaderModeReceivedDistillability(source_id)
         .SetIsPageDistillable(result.is_distillable)
         .Record(ukm::UkmRecorder::Get());
diff --git a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
index 6675a54..ac22d80 100644
--- a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
@@ -55,7 +55,7 @@
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     content::RenderProcessHost* process =
-        web_contents->GetMainFrame()->GetProcess();
+        web_contents->GetPrimaryMainFrame()->GetProcess();
     content::RenderProcessHostWatcher crash_observer(
         process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
     process->Shutdown(content::RESULT_CODE_KILLED);
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index c2f926a..20012b5 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -176,7 +176,7 @@
 
   if (web_contents) {
     return base::StringPrintf(
-        "web.%d", web_contents->GetMainFrame()->GetFrameTreeNodeId());
+        "web.%d", web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId());
   }
   LOG(ERROR) << "Unable to generate a RoutingID";
   return "";
@@ -363,11 +363,11 @@
   dialog->selection_index_ = 0;
 }
 
-content::RenderFrameHost* SelectFileDialogExtension::GetMainFrame() {
+content::RenderFrameHost* SelectFileDialogExtension::GetPrimaryMainFrame() {
   if (extension_dialog_)
     return extension_dialog_->host()->main_frame_host();
   else if (system_files_app_web_contents_)
-    return system_files_app_web_contents_->GetMainFrame();
+    return system_files_app_web_contents_->GetPrimaryMainFrame();
   return nullptr;
 }
 
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.h b/chrome/browser/ui/views/select_file_dialog_extension.h
index 9bf4e2f..d3d212d 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.h
+++ b/chrome/browser/ui/views/select_file_dialog_extension.h
@@ -87,7 +87,7 @@
                             Profile* profile);
 
   // Allows access to the extension's main frame for injecting javascript.
-  content::RenderFrameHost* GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame();
 
   // Call SelectFile with params specific to Chrome OS file manager.
   // |owner| specifies the window and app type that opened the dialog.
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
index 767a28b..c952f5a 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -252,7 +252,7 @@
   }
 
   void CheckJavascriptErrors() {
-    content::RenderFrameHost* host = dialog_->GetMainFrame();
+    content::RenderFrameHost* host = dialog_->GetPrimaryMainFrame();
     base::Value value =
         content::ExecuteScriptAndGetValue(host, "window.JSErrorCount");
     int js_error_count = value.GetInt();
@@ -260,7 +260,7 @@
   }
 
   void ClickElement(const std::string& selector) {
-    content::RenderFrameHost* frame_host = dialog_->GetMainFrame();
+    content::RenderFrameHost* frame_host = dialog_->GetPrimaryMainFrame();
 
     auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host);
     CHECK(web_contents);
@@ -365,7 +365,7 @@
   void CloseDialog(DialogButtonType button_type,
                    const gfx::NativeWindow& owning_window) {
     // Inject JavaScript into the dialog to click the dialog |button_type|.
-    content::RenderFrameHost* frame_host = dialog_->GetMainFrame();
+    content::RenderFrameHost* frame_host = dialog_->GetPrimaryMainFrame();
 
     ClickJsButton(frame_host, button_type);
 
@@ -423,7 +423,7 @@
                                      base::FilePath(), owning_window, ""));
 
   // Get the Files app WebContents/Framehost, before deleting the dialog_.
-  content::RenderFrameHost* frame_host = dialog_->GetMainFrame();
+  content::RenderFrameHost* frame_host = dialog_->GetPrimaryMainFrame();
 
   // Some users of SelectFileDialog destroy their listener before cleaning
   // up the dialog, delete the `dialog_`, however the
@@ -673,7 +673,7 @@
   // Open the file dialog on the default path.
   ASSERT_NO_FATAL_FAILURE(OpenDialog(ui::SelectFileDialog::SELECT_OPEN_FILE,
                                      base::FilePath(), owning_window, ""));
-  content::RenderFrameHost* frame_host = dialog_->GetMainFrame();
+  content::RenderFrameHost* frame_host = dialog_->GetPrimaryMainFrame();
   aura::Window* dialog_window =
       frame_host->GetNativeView()->GetToplevelWindow();
   auto* color_provider = ash::ColorProvider::Get();
@@ -716,7 +716,7 @@
   // Open the file dialog on the default path.
   ASSERT_NO_FATAL_FAILURE(OpenDialog(ui::SelectFileDialog::SELECT_OPEN_FILE,
                                      base::FilePath(), owning_window, ""));
-  content::RenderFrameHost* frame_host = dialog_->GetMainFrame();
+  content::RenderFrameHost* frame_host = dialog_->GetPrimaryMainFrame();
   aura::Window* dialog_window =
       frame_host->GetNativeView()->GetToplevelWindow();
 
diff --git a/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc b/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
index 6d23df3..9767f0d 100644
--- a/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
+++ b/chrome/browser/ui/views/sharing/click_to_call_browsertest.cc
@@ -380,7 +380,7 @@
       ->set_on_dialog_shown_closure_for_testing(run_loop.QuitClosure());
 
   // Click on the tel link to trigger the bubble view.
-  web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.querySelector('a').click();", base::NullCallback());
   // Wait until the bubble is visible.
   run_loop.Run();
@@ -409,7 +409,7 @@
   controller->set_on_dialog_shown_closure_for_testing(run_loop.QuitClosure());
 
   // Click on the tel link to trigger the bubble view.
-  web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.querySelector('a').click();", base::NullCallback());
   // Wait until the bubble is visible.
   run_loop.Run();
@@ -479,7 +479,7 @@
       ->set_on_dialog_shown_closure_for_testing(run_loop.QuitClosure());
 
   // Click on the tel link to trigger the bubble view.
-  web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.querySelector('a').click();", base::NullCallback());
   // Wait until the bubble is visible.
   run_loop.Run();
diff --git a/chrome/browser/ui/views/sharing/sharing_browsertest.cc b/chrome/browser/ui/views/sharing/sharing_browsertest.cc
index a3b3b3f..1683060 100644
--- a/chrome/browser/ui/views/sharing/sharing_browsertest.cc
+++ b/chrome/browser/ui/views/sharing/sharing_browsertest.cc
@@ -185,7 +185,7 @@
   params.writing_direction_right_to_left = 0;
 #endif
   auto menu = std::make_unique<TestRenderViewContextMenu>(
-      *web_contents_->GetMainFrame(), params);
+      *web_contents_->GetPrimaryMainFrame(), params);
   menu->Init();
   return menu;
 }
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
index d2ddaf39..17c9ae2 100644
--- a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
+++ b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
@@ -57,7 +57,7 @@
                       content::WebContents* web_contents) {
   return data.initiating_origin &&
          !data.initiating_origin->IsSameOriginWith(
-             web_contents->GetMainFrame()->GetLastCommittedOrigin());
+             web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 }
 
 std::u16string PrepareHelpTextWithoutOrigin(const SharingDialogData& data) {
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
index 919d2ea..5c0c3fd 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
@@ -107,7 +107,8 @@
 
   // Read Anything just runs on the main frame and does not run on embedded
   // content.
-  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* render_frame_host =
+      web_contents->GetPrimaryMainFrame();
   if (!render_frame_host)
     return;
 
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc
index 111c66b..5cd2d92 100644
--- a/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc
@@ -735,8 +735,9 @@
   EXPECT_NE(nullptr, GetSidePanelContentsFor(browser(), 1));
 
   // Simulate a crash in the hosted side panel contents.
-  auto* rph_second_tab =
-      GetSidePanelContentsFor(browser(), 1)->GetMainFrame()->GetProcess();
+  auto* rph_second_tab = GetSidePanelContentsFor(browser(), 1)
+                             ->GetPrimaryMainFrame()
+                             ->GetProcess();
   content::RenderProcessHostWatcher crash_observer_second_tab(
       rph_second_tab,
       content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
@@ -749,8 +750,9 @@
 
   // Simulate a crash in the side panel contents of the first tab which is not
   // currently active.
-  auto* rph_first_tab =
-      GetSidePanelContentsFor(browser(), 0)->GetMainFrame()->GetProcess();
+  auto* rph_first_tab = GetSidePanelContentsFor(browser(), 0)
+                            ->GetPrimaryMainFrame()
+                            ->GetProcess();
   content::RenderProcessHostWatcher crash_observer_first_tab(
       rph_first_tab, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   EXPECT_TRUE(rph_first_tab->Shutdown(content::RESULT_CODE_KILLED));
diff --git a/chrome/browser/ui/views/sync/inline_login_ui_browsertest.cc b/chrome/browser/ui/views/sync/inline_login_ui_browsertest.cc
index 8186333..3642cfa0 100644
--- a/chrome/browser/ui/views/sync/inline_login_ui_browsertest.cc
+++ b/chrome/browser/ui/views/sync/inline_login_ui_browsertest.cc
@@ -111,7 +111,8 @@
       ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
   content::WebContents* contents =
       browser->tab_strip_model()->GetActiveWebContents();
-  content::RenderProcessHost* process = contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* process =
+      contents->GetPrimaryMainFrame()->GetProcess();
   return ContentInfo(contents, process->GetID(),
                      process->GetStoragePartition());
 }
@@ -313,7 +314,7 @@
   ASSERT_EQ(1u, set.size());
   content::WebContents* webview_contents = *set.begin();
   content::RenderProcessHost* process =
-      webview_contents->GetMainFrame()->GetProcess();
+      webview_contents->GetPrimaryMainFrame()->GetProcess();
   ASSERT_NE(info.pid, process->GetID());
   ASSERT_NE(info.storage_partition, process->GetStoragePartition());
 }
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc
index 34a1263b..c2059c4 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc
@@ -25,5 +25,6 @@
       CreateWebContentsViewDelegate(web_contents());
   EXPECT_FALSE(web_contents()->GetFocusedFrame());
   const content::ContextMenuParams params;
-  delegate_view->ShowContextMenu(*web_contents()->GetMainFrame(), params);
+  delegate_view->ShowContextMenu(*web_contents()->GetPrimaryMainFrame(),
+                                 params);
 }
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
index 7a1917e7..39fc5f1f 100644
--- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
+++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
@@ -60,7 +60,7 @@
 std::u16string GetTabName(WebContents* tab) {
   const std::u16string formatted_origin =
       url_formatter::FormatOriginForSecurityDisplay(
-          tab->GetMainFrame()->GetLastCommittedOrigin());
+          tab->GetPrimaryMainFrame()->GetLastCommittedOrigin());
   return formatted_origin.empty() ? tab->GetTitle() : formatted_origin;
 }
 
@@ -68,7 +68,7 @@
   if (!web_contents) {
     return GlobalRenderFrameHostId();
   }
-  auto* const main_frame = web_contents->GetMainFrame();
+  auto* const main_frame = web_contents->GetPrimaryMainFrame();
   return main_frame ? main_frame->GetGlobalId() : GlobalRenderFrameHostId();
 }
 
@@ -192,7 +192,7 @@
   DCHECK(shared_tab);
   DCHECK_EQ(infobars_[shared_tab], infobar);
 
-  RenderFrameHost* main_frame = shared_tab->GetMainFrame();
+  RenderFrameHost* main_frame = shared_tab->GetPrimaryMainFrame();
   DCHECK(main_frame);
   source_callback_.Run(content::DesktopMediaID(
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
@@ -415,7 +415,7 @@
   bool is_sharing_allowed_by_policy =
       !capturer_restricted_to_same_origin_ ||
       capturer_origin_.IsSameOriginWith(
-          contents->GetMainFrame()->GetLastCommittedOrigin());
+          contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
 
 #if BUILDFLAG(IS_CHROMEOS)
   // Check if dlp policies allow sharing.
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
index 531dda2..5baa09d6 100644
--- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
+++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views_browsertest.cc
@@ -49,7 +49,7 @@
 }
 
 content::GlobalRenderFrameHostId GetGlobalId(Browser* browser, int tab) {
-  auto* const main_frame = GetWebContents(browser, tab)->GetMainFrame();
+  auto* const main_frame = GetWebContents(browser, tab)->GetPrimaryMainFrame();
   return main_frame ? main_frame->GetGlobalId()
                     : content::GlobalRenderFrameHostId();
 }
@@ -93,7 +93,7 @@
 
 std::u16string GetExpectedSwitchToMessage(Browser* browser, int tab) {
   content::RenderFrameHost* const rfh =
-      GetWebContents(browser, tab)->GetMainFrame();
+      GetWebContents(browser, tab)->GetPrimaryMainFrame();
   return l10n_util::GetStringFUTF16(
       IDS_TAB_SHARING_INFOBAR_SWITCH_TO_BUTTON,
       url_formatter::FormatOriginForSecurityDisplay(
@@ -103,7 +103,7 @@
 
 content::DesktopMediaID GetDesktopMediaID(Browser* browser, int tab) {
   content::RenderFrameHost* main_frame =
-      GetWebContents(browser, tab)->GetMainFrame();
+      GetWebContents(browser, tab)->GetPrimaryMainFrame();
   return content::DesktopMediaID(
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
       content::DesktopMediaID::kNullId,
@@ -501,7 +501,7 @@
   // Kill a tab different than the shared one.
   content::WebContents* web_contents = GetWebContents(browser(), 0);
   content::RenderProcessHost* process =
-      web_contents->GetMainFrame()->GetProcess();
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   process->Shutdown(content::RESULT_CODE_KILLED);
@@ -524,7 +524,7 @@
   // Kill the shared tab.
   content::WebContents* shared_tab_web_contents = GetWebContents(browser(), 1);
   content::RenderProcessHost* shared_tab_process =
-      shared_tab_web_contents->GetMainFrame()->GetProcess();
+      shared_tab_web_contents->GetPrimaryMainFrame()->GetProcess();
   content::RenderProcessHostWatcher shared_tab_crash_observer(
       shared_tab_process,
       content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
diff --git a/chrome/browser/ui/views/tooltip/tooltip_browsertest.cc b/chrome/browser/ui/views/tooltip/tooltip_browsertest.cc
index cc92893..bdb37e4 100644
--- a/chrome/browser/ui/views/tooltip/tooltip_browsertest.cc
+++ b/chrome/browser/ui/views/tooltip/tooltip_browsertest.cc
@@ -119,7 +119,7 @@
         browser(), embedded_test_server()->GetURL("a.com", relative_url)));
     web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
     rwhv_ = web_contents_->GetRenderWidgetHostView();
-    content::WaitForHitTestData(web_contents_->GetMainFrame());
+    content::WaitForHitTestData(web_contents_->GetPrimaryMainFrame());
   }
 
   void LoadCrossSitePageIntoFrame(const std::string& relative_url,
@@ -137,7 +137,7 @@
   }
 
   RenderFrameHost* GetChildRenderFrameHost(size_t index) {
-    return ChildFrameAt(web_contents_->GetMainFrame(), index);
+    return ChildFrameAt(web_contents_->GetPrimaryMainFrame(), index);
   }
 
   bool SkipTestForOldWinVersion() const {
diff --git a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc
index 7e90e04..6ea0dff 100644
--- a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc
@@ -234,7 +234,7 @@
       ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAppsURL)));
   auto waiter = views::NamedWidgetShownWaiter(
       views::test::AnyWidgetTestPasskey{}, "DeprecatedAppsDialogView");
-  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"document.getElementById('deprecated-apps-link').click()",
       base::NullCallback());
   EXPECT_NE(waiter.WaitIfNeededAndGet(), nullptr);
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
index 9038af7..b0ee834 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -666,7 +666,7 @@
   gfx::Rect new_bounds = helper()->browser_view()->GetLocalBounds();
   new_bounds.set_width(new_bounds.width() + 10);
   content::TitleWatcher title_watcher(web_contents, u"onresize");
-  EXPECT_TRUE(ExecJs(web_contents->GetMainFrame(), kTestScript));
+  EXPECT_TRUE(ExecJs(web_contents->GetPrimaryMainFrame(), kTestScript));
   helper()->browser_view()->GetWidget()->SetBounds(new_bounds);
   title_watcher.AlsoWaitForTitle(u"ongeometrychange");
   EXPECT_EQ(u"onresize", title_watcher.WaitAndGetTitle());
@@ -678,7 +678,7 @@
   // Validate event is not fired.
   new_bounds.set_width(new_bounds.width() - 10);
   content::TitleWatcher title_watcher2(web_contents, u"onresize");
-  EXPECT_TRUE(ExecJs(web_contents->GetMainFrame(), kTestScript));
+  EXPECT_TRUE(ExecJs(web_contents->GetPrimaryMainFrame(), kTestScript));
   helper()->browser_view()->GetWidget()->SetBounds(new_bounds);
   title_watcher2.AlsoWaitForTitle(u"ongeometrychange");
   EXPECT_EQ(u"onresize", title_watcher2.WaitAndGetTitle());
@@ -701,8 +701,8 @@
   content::WebContents* popup_web_contents =
       popup_browser_view->GetActiveWebContents();
 
-  EXPECT_TRUE(
-      content::WaitForRenderFrameReady(popup_web_contents->GetMainFrame()));
+  EXPECT_TRUE(content::WaitForRenderFrameReady(
+      popup_web_contents->GetPrimaryMainFrame()));
   EXPECT_FALSE(popup_browser_view->IsWindowControlsOverlayEnabled());
   EXPECT_FALSE(EvalJs(popup_web_contents,
                       "window.navigator.windowControlsOverlay.visible")
@@ -732,8 +732,8 @@
       BrowserView::GetBrowserViewForBrowser(popup);
   content::WebContents* popup_web_contents =
       popup_browser_view->GetActiveWebContents();
-  EXPECT_TRUE(
-      content::WaitForRenderFrameReady(popup_web_contents->GetMainFrame()));
+  EXPECT_TRUE(content::WaitForRenderFrameReady(
+      popup_web_contents->GetPrimaryMainFrame()));
 
   // When popup is opened pointing to any other site, it will not know whether
   // the popup app uses WCO or not. This test also ensures it does not crash.
@@ -769,7 +769,8 @@
 
   std::string kCSSTitlebarRect = GetCSSTitlebarRect();
   auto* web_contents = helper()->browser_view()->GetActiveWebContents();
-  EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), kCSSTitlebarRect));
+  EXPECT_TRUE(
+      ExecuteScript(web_contents->GetPrimaryMainFrame(), kCSSTitlebarRect));
 
   const std::string kRectListString =
       "var rect = [titlebarAreaXInt, titlebarAreaYInt, "
@@ -802,7 +803,8 @@
   new_bounds.set_height(new_bounds.height() + 20);
   ResizeWindowBoundsAndWait(new_bounds);
 
-  EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), kCSSTitlebarRect));
+  EXPECT_TRUE(
+      ExecuteScript(web_contents->GetPrimaryMainFrame(), kCSSTitlebarRect));
 
   base::Value::ListStorage updated_rect_list =
       helper()->GetXYWidthHeightListValue(
@@ -826,7 +828,8 @@
 
   std::string kCSSTitlebarRect = GetCSSTitlebarRect();
   auto* web_contents = helper()->browser_view()->GetActiveWebContents();
-  EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), kCSSTitlebarRect));
+  EXPECT_TRUE(
+      ExecuteScript(web_contents->GetPrimaryMainFrame(), kCSSTitlebarRect));
 
   const std::string kRectListString =
       "var rect = [titlebarAreaXInt, titlebarAreaYInt, "
@@ -854,7 +857,8 @@
   new_bounds.set_height(new_bounds.height() + 15);
   ResizeWindowBoundsAndWait(new_bounds);
 
-  EXPECT_TRUE(ExecuteScript(web_contents->GetMainFrame(), kCSSTitlebarRect));
+  EXPECT_TRUE(
+      ExecuteScript(web_contents->GetPrimaryMainFrame(), kCSSTitlebarRect));
 
   base::Value::ListStorage updated_rect_list =
       helper()->GetXYWidthHeightListValue(
@@ -1064,7 +1068,7 @@
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   content::RenderFrameHost* fenced_frame_rfh =
       fenced_frame_helper_.CreateFencedFrame(
-          browser_view->GetActiveWebContents()->GetMainFrame(),
+          browser_view->GetActiveWebContents()->GetPrimaryMainFrame(),
           fenced_frame_url);
   ASSERT_NE(nullptr, fenced_frame_rfh);
   EXPECT_FALSE(browser_view->ShouldDescendIntoChildForEventHandling(
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.cc
index c14000e64..388cf7b 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.cc
@@ -135,7 +135,7 @@
     content::WebContents* web_contents,
     const std::string& rect_value_list,
     const std::string& rect_var_name) {
-  EXPECT_TRUE(ExecJs(web_contents->GetMainFrame(), rect_value_list));
+  EXPECT_TRUE(ExecJs(web_contents->GetPrimaryMainFrame(), rect_value_list));
   return EvalJs(web_contents, rect_var_name).ExtractList().TakeListDeprecated();
 }
 
@@ -152,7 +152,7 @@
 void WebAppFrameToolbarTestHelper::SetupGeometryChangeCallback(
     content::WebContents* web_contents) {
   EXPECT_TRUE(
-      ExecJs(web_contents->GetMainFrame(),
+      ExecJs(web_contents->GetPrimaryMainFrame(),
              "var geometrychangeCount = 0;"
              "document.title = 'beforegeometrychange';"
              "navigator.windowControlsOverlay.ongeometrychange = (e) => {"
diff --git a/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc b/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
index f8ef118f7..57a1be0 100644
--- a/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
+++ b/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
@@ -227,8 +227,9 @@
   CheckMixedContentFailedToLoad(app_browser);
 
   // Change the mixed content to be acceptable.
-  content::RenderFrameHost* main_frame =
-      app_browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = app_browser->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   content::RenderFrameHost* iframe = content::ChildFrameAt(main_frame, 0);
   EXPECT_TRUE(TryToLoadImage(
       iframe, embedded_test_server()->GetURL("foo.com", kImagePath)));
@@ -257,8 +258,10 @@
 
   chrome::OpenInChrome(app_browser);
 
-  content::RenderFrameHost* main_frame =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* main_frame = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
   content::RenderFrameHost* iframe = content::ChildFrameAt(main_frame, 0);
 
   EXPECT_TRUE(TryToLoadImage(
diff --git a/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc b/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
index c1dc969f..ee3a605 100644
--- a/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
+++ b/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
@@ -59,7 +59,7 @@
     if (!web_contents) {
       web_contents = browser()->tab_strip_model()->GetActiveWebContents();
     }
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   }
 
   GURL GetURL(const std::string& url) {
diff --git a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
index 1fbdc58..abb7223 100644
--- a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
+++ b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
@@ -225,9 +225,11 @@
   content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
   observer.StartWatchingNewWebContents();
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -268,9 +270,11 @@
   content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
   observer.StartWatchingNewWebContents();
 
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, 0);
 
diff --git a/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc b/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
index a72339b2..52be64e 100644
--- a/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
@@ -70,7 +70,7 @@
     auto frames = CollectAllRenderFrameHosts(web_contents->GetPrimaryPage());
     ASSERT_EQ(4u, frames.size());
 
-    main_frame_ = web_contents->GetMainFrame();
+    main_frame_ = web_contents->GetPrimaryMainFrame();
     for (auto* frame : frames) {
       if (frame->GetLastCommittedURL() == sub_start_url) {
         sub_app_frame_ = frame;
@@ -476,7 +476,7 @@
       OpenURLOffTheRecord(profile(), main_frame_->GetLastCommittedURL());
   RenderFrameHost* incognito_frame = incognito_browser->tab_strip_model()
                                          ->GetActiveWebContents()
-                                         ->GetMainFrame();
+                                         ->GetPrimaryMainFrame();
 
   ASSERT_TRUE(
       content::ExecuteScript(incognito_frame, "navigator.setAppBadge()"));
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index 69ac6b3..05a1573 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -1023,8 +1023,8 @@
   {
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
     content::RenderFrameDeletedObserver crash_observer(
-        tab_contents->GetMainFrame());
-    tab_contents->GetMainFrame()->GetProcess()->Shutdown(1);
+        tab_contents->GetPrimaryMainFrame());
+    tab_contents->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
     crash_observer.WaitUntilDeleted();
   }
   ASSERT_TRUE(tab_contents->IsCrashed());
@@ -1476,7 +1476,9 @@
   Browser* const app_browser = LaunchWebAppBrowserAndWait(app_id);
 
   content::RenderFrameHost* const render_frame_host =
-      app_browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+      app_browser->tab_strip_model()
+          ->GetActiveWebContents()
+          ->GetPrimaryMainFrame();
   EXPECT_TRUE(content::ExecuteScript(
       render_frame_host,
       "navigator.geolocation.getCurrentPosition(function(){});"));
@@ -1658,7 +1660,7 @@
   // Ensure that the frame navigated successfully and that it has correct
   // content.
   content::RenderFrameHost* const subframe =
-      content::ChildFrameAt(tab->GetMainFrame(), 0);
+      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(app_url, subframe->GetLastCommittedURL());
   EXPECT_EQ(
       "This page has no title.",
diff --git a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
index 2ed1c0d..e6bc312 100644
--- a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
@@ -117,8 +117,8 @@
   EXPECT_EQ(
       content::PAGE_TYPE_NORMAL,
       new_contents->GetController().GetLastCommittedEntry()->GetPageType());
-  EXPECT_EQ(contents->GetMainFrame()->GetSiteInstance(),
-            new_contents->GetMainFrame()->GetSiteInstance());
+  EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance(),
+            new_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   return new_contents;
 }
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
index 07b3ca2..8c210f6 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -123,7 +123,7 @@
     return absl::nullopt;
 
   return provider->registrar().FindInstalledAppWithUrlInScope(
-      web_contents->GetMainFrame()->GetLastCommittedURL());
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedURL());
 }
 
 void PrunePreScopeNavigationHistory(const GURL& scope,
diff --git a/chrome/browser/ui/web_applications/web_app_menu_model.cc b/chrome/browser/ui/web_applications/web_app_menu_model.cc
index b0765fd..5b7b9ea 100644
--- a/chrome/browser/ui/web_applications/web_app_menu_model.cc
+++ b/chrome/browser/ui/web_applications/web_app_menu_model.cc
@@ -116,7 +116,7 @@
   // Isolated apps shouldn't be opened in Chrome.
   bool is_isolated_app =
       web_contents &&
-      web_contents->GetMainFrame()->GetWebExposedIsolationLevel() >=
+      web_contents->GetPrimaryMainFrame()->GetWebExposedIsolationLevel() >=
           WebExposedIsolationLevel::kMaybeIsolatedApplication;
   if (!is_isolated_app)
     AddItemWithStringId(IDC_OPEN_IN_CHROME, IDS_OPEN_IN_CHROME);
diff --git a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
index 16c7acb..94b25975 100644
--- a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
@@ -182,7 +182,7 @@
 
     const scoped_refptr<storage::FileSystemContext> file_system_context =
         file_manager::util::GetFileSystemContextForRenderFrameHost(
-            profile(), contents->GetMainFrame());
+            profile(), contents->GetPrimaryMainFrame());
     chromeos::RecentModel::GetForProfile(profile())->GetRecentFiles(
         file_system_context.get(),
         /*origin=*/GURL(),
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 bc9d26c5..b917df9 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -1328,7 +1328,7 @@
   if (!function)
     return nullptr;
 
-  if (web_ui->GetWebContents()->GetMainFrame())
+  if (web_ui->GetWebContents()->GetPrimaryMainFrame())
     webui::LogWebUIUrl(url);
 
   return base::WrapUnique((*function)(web_ui, url));
diff --git a/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc b/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc
index f781d64..0de9289 100644
--- a/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc
+++ b/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc
@@ -43,7 +43,7 @@
                        DisallowEmbeddingChromeSchemeFromWebFrameBrowserCheck) {
   GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
 
   // Add iframe but don't navigate it to a chrome:// URL yet.
@@ -76,7 +76,7 @@
     DisallowEmbeddingChromeUntrustedSchemeFromWebFrameBrowserCheck) {
   GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-  auto* main_frame = web_contents->GetMainFrame();
+  auto* main_frame = web_contents->GetPrimaryMainFrame();
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
 
   // Add iframe but don't navigate it to a chrome-untrusted:// URL yet.
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
index 1d4d72d..6ed2f54 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
@@ -173,7 +173,7 @@
 }
 
 void CrostiniInstallerUI::ClickInstallForTesting() {
-  web_ui()->GetWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
+  web_ui()->GetWebContents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
       u"const app = document.querySelector('crostini-installer-app');"
       // If flag CrostiniUsername or CrostiniDiskResizing is turned on, there
       // will be a "next" button and we should click it to go to the config page
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
index 07acde0..8e091fc 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
@@ -107,7 +107,7 @@
 
     dialog_delegate_ = std::make_unique<TestConstrainedWebDialogDelegate>();
     dialog_ = std::make_unique<ConstrainedWebDialogUI>(web_ui_.get());
-    dialog_->WebUIRenderFrameCreated(web_contents_->GetMainFrame());
+    dialog_->WebUIRenderFrameCreated(web_contents_->GetPrimaryMainFrame());
 
     ConstrainedWebDialogUI::SetConstrainedDelegate(web_contents_.get(),
                                                    dialog_delegate_.get());
diff --git a/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc
index ddff291a..e1851d45 100644
--- a/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc
+++ b/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc
@@ -189,7 +189,8 @@
   if (!file)
     return;
   content::WebContents* web_contents = GetWebUIWebContents();
-  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+  content::RenderFrameHost* render_frame_host =
+      web_contents->GetPrimaryMainFrame();
   const GURL url = file->GetURL();
 
   net::NetworkTrafficAnnotationTag traffic_annotation =
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
index 3ef8aa9..27824bd 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
@@ -143,7 +143,7 @@
   // Open the view-source of the options page.
   int old_tabs_count = browser()->tab_strip_model()->count();
   content::WebContentsAddedObserver view_source_contents_added_observer;
-  options_contents->GetMainFrame()->ViewSource();
+  options_contents->GetPrimaryMainFrame()->ViewSource();
   content::WebContents* view_source_contents =
       view_source_contents_added_observer.GetWebContents();
   ASSERT_TRUE(view_source_contents);
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 e467177a..0da8dd11 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -259,14 +259,14 @@
   if (!profile_->GetPrefs()->GetBoolean(
           ::prefs::kAllowDeletingBrowserHistory) ||
       visits.empty()) {
-    std::move(callback).Run(false);
+    std::move(callback).Run(/*success=*/false);
     return;
   }
 
-  // If there's already a pending deletion, we have to fail here, because
+  // If there's a pending request for deletion, we have to fail here, because
   // `BrowsingHistoryService` only supports one deletion request at a time.
-  if (!pending_deletion_.empty()) {
-    std::move(callback).Run(false);
+  if (!pending_remove_visits_callback_.is_null()) {
+    std::move(callback).Run(/*success=*/false);
     return;
   }
 
@@ -285,11 +285,12 @@
     }
   }
 
-  // Transfer the visits to be deleted to the pending member variable.
-  pending_deletion_ = std::move(visits);
+  // Transfer the visits pending deletion and the respective callback to member
+  // variables.
+  pending_remove_visits_ = std::move(visits);
+  pending_remove_visits_callback_ = std::move(callback);
 
   browsing_history_service_->RemoveVisits(items_to_remove);
-  std::move(callback).Run(true);
 }
 
 void HistoryClustersHandler::OpenVisitUrlsInTabGroup(
@@ -333,21 +334,22 @@
 }
 
 void HistoryClustersHandler::OnDebugMessage(const std::string& message) {
-  content::RenderFrameHost* rfh = web_contents_->GetMainFrame();
+  content::RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
   if (rfh && GetConfig().non_user_visible_debug) {
     rfh->AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kInfo, message);
   }
 }
 
 void HistoryClustersHandler::OnRemoveVisitsComplete() {
-  page_->OnVisitsRemoved(std::move(pending_deletion_));
-  pending_deletion_.clear();
+  DCHECK(!pending_remove_visits_callback_.is_null());
+  std::move(pending_remove_visits_callback_).Run(/*success=*/true);
+  // Notify the page of the successfully deleted visits to update the UI.
+  page_->OnVisitsRemoved(std::move(pending_remove_visits_));
 }
 
 void HistoryClustersHandler::OnRemoveVisitsFailed() {
-  // The WebUI page doesn't expect or need a notification if the deletion
-  // failed at the History backend layer.
-  pending_deletion_.clear();
+  DCHECK(!pending_remove_visits_callback_.is_null());
+  std::move(pending_remove_visits_callback_).Run(/*success=*/false);
 }
 
 Profile* HistoryClustersHandler::GetProfile() {
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 cfe048b..f372f88 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -108,10 +108,11 @@
   // querying with HistoryClustersService.
   std::unique_ptr<history::BrowsingHistoryService> browsing_history_service_;
 
-  // Holds the visits we requested to be deleted. We can only handle one
-  // deletion request at a time, and that's a limitation built into
-  // `BrowsingHistoryService`.
-  std::vector<mojom::URLVisitPtr> pending_deletion_;
+  // The following variables hold the visits requested to be deleted and the
+  // callback for the respective request. `BrowsingHistoryService` can only
+  // handle one deletion request at a time.
+  std::vector<mojom::URLVisitPtr> pending_remove_visits_;
+  RemoveVisitsCallback pending_remove_visits_callback_;
 
   base::WeakPtrFactory<HistoryClustersHandler> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/webui/inspect_ui_browsertest.cc b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
index 7fe46cd..83de889 100644
--- a/chrome/browser/ui/webui/inspect_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
@@ -177,7 +177,7 @@
   const GURL fenced_frame_url =
       embedded_test_server()->GetURL("/fenced_frames/title1.html");
   ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
-      front_end_tab->GetMainFrame(), fenced_frame_url));
+      front_end_tab->GetPrimaryMainFrame(), fenced_frame_url));
 
   // Ensure that the fenced frame doesn't affect to the the front-end observer.
   // "Inspect Native UI" button is still disabled.
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
index 88dd1a63..30c8daa 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -307,7 +307,7 @@
     }
   }
   const content::GlobalRenderFrameHostId primary_main_frame_id =
-      web_contents->GetMainFrame()->GetGlobalId();
+      web_contents->GetPrimaryMainFrame()->GetGlobalId();
   safe_browsing::SafeBrowsingBlockingPage::UnsafeResource resource;
   resource.url = request_url;
   resource.is_subresource = request_url != main_frame_url;
@@ -363,7 +363,7 @@
     }
   }
   const content::GlobalRenderFrameHostId primary_main_frame_id =
-      web_contents->GetMainFrame()->GetGlobalId();
+      web_contents->GetPrimaryMainFrame()->GetGlobalId();
   safe_browsing::SafeBrowsingBlockingPage::UnsafeResource resource;
   resource.url = request_url;
   resource.is_subresource = request_url != main_frame_url;
diff --git a/chrome/browser/ui/webui/new_tab_page/webui_ntp_browsertest.cc b/chrome/browser/ui/webui/new_tab_page/webui_ntp_browsertest.cc
index 0ebd231..51ab721 100644
--- a/chrome/browser/ui/webui/new_tab_page/webui_ntp_browsertest.cc
+++ b/chrome/browser/ui/webui/new_tab_page/webui_ntp_browsertest.cc
@@ -56,8 +56,9 @@
   ASSERT_EQ(ntp_url, web_contents->GetLastCommittedURL());
 
   GURL webui_ntp_url(chrome::kChromeUINewTabPageURL);
-  ASSERT_EQ(webui_ntp_url,
-            web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+  ASSERT_EQ(
+      webui_ntp_url,
+      web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
 }
 
 // Verify that the WebUI NTP uses process-per-site.
@@ -82,8 +83,8 @@
 
   // Verify that all NTPs share a process.
   for (size_t i = 1; i < tabs.size(); i++) {
-    EXPECT_EQ(tabs[0]->GetMainFrame()->GetProcess(),
-              tabs[i]->GetMainFrame()->GetProcess());
+    EXPECT_EQ(tabs[0]->GetPrimaryMainFrame()->GetProcess(),
+              tabs[i]->GetPrimaryMainFrame()->GetProcess());
   }
 }
 
@@ -109,7 +110,7 @@
   ExpectIsWebUiNtp(ntp);
 
   // Check spare was taken.
-  EXPECT_EQ(ntp->GetMainFrame()->GetProcess(), spare);
+  EXPECT_EQ(ntp->GetPrimaryMainFrame()->GetProcess(), spare);
 
   // No processes should be unnecessarily terminated.
   EXPECT_EQ(0u, process_termination_tracker.size());
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index af3b160..87614ef 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -1183,7 +1183,7 @@
 
 void PrintPreviewHandler::BadMessageReceived() {
   bad_message::ReceivedBadMessage(
-      GetInitiator()->GetMainFrame()->GetProcess(),
+      GetInitiator()->GetPrimaryMainFrame()->GetProcess(),
       bad_message::BadMessageReason::PPH_EXTRA_PREVIEW_MESSAGE);
 }
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index 64231682..550e6de3 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -397,12 +397,12 @@
     // Ensure the initiator has a RenderFrameHost with a live RenderFrame, as
     // the print code will not bother to send IPCs to a non-live RenderFrame.
     content::NavigationSimulator::NavigateAndCommitFromDocument(
-        GURL("about:blank"), initiator->GetMainFrame());
+        GURL("about:blank"), initiator->GetPrimaryMainFrame());
     preview_web_contents_ = content::WebContents::Create(
         content::WebContents::CreateParams(&profile_));
     PrintViewManager::CreateForWebContents(initiator);
     PrintViewManager::FromWebContents(initiator)->PrintPreviewNow(
-        initiator->GetMainFrame(), false);
+        initiator->GetPrimaryMainFrame(), false);
     web_ui_ = std::make_unique<content::TestWebUI>();
     web_ui_->set_web_contents(preview_web_contents_.get());
 
@@ -669,7 +669,7 @@
 
   blink::AssociatedInterfaceProvider*
   GetInitiatorAssociatedInterfaceProvider() {
-    return initiator_web_contents_->GetMainFrame()
+    return initiator_web_contents_->GetPrimaryMainFrame()
         ->GetRemoteAssociatedInterfaces();
   }
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
index 7622dc3c..d4c5673 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -73,7 +73,7 @@
 
   PrintViewManager* print_view_manager =
       PrintViewManager::FromWebContents(initiator);
-  print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false);
+  print_view_manager->PrintPreviewNow(initiator->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
 
   EXPECT_NE(initiator, preview_dialog);
@@ -118,7 +118,7 @@
 
   PrintViewManager* print_view_manager =
       PrintViewManager::FromWebContents(initiator);
-  print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false);
+  print_view_manager->PrintPreviewNow(initiator->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
 
   EXPECT_NE(initiator, preview_dialog);
@@ -176,7 +176,7 @@
 
   PrintViewManager* print_view_manager =
       PrintViewManager::FromWebContents(initiator);
-  print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false);
+  print_view_manager->PrintPreviewNow(initiator->GetPrimaryMainFrame(), false);
   WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
 
   EXPECT_NE(initiator, preview_dialog);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
index 1e45dcf..5dcfca3 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
@@ -238,7 +238,7 @@
   }
   print_view_manager->PrintForPrintPreview(
       std::move(job_settings), std::move(print_data),
-      preview_web_contents->GetMainFrame(), std::move(callback));
+      preview_web_contents->GetPrimaryMainFrame(), std::move(callback));
 }
 
 bool ParseSettings(const base::Value::Dict& settings,
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
index f12bac8d83..a1f2a7b 100644
--- a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
+++ b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
@@ -63,8 +63,10 @@
   // When the user tries to enable the feature, show the modal dialog. The
   // dialog will disable the feature again if it is not accepted.
   content::WebContents* web_contents = web_ui()->GetWebContents();
-  content::RenderWidgetHostView* view =
-      web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget()->GetView();
+  content::RenderWidgetHostView* view = web_contents->GetPrimaryMainFrame()
+                                            ->GetRenderViewHost()
+                                            ->GetWidget()
+                                            ->GetView();
   gfx::Rect rect = view->GetViewBounds();
   auto model = std::make_unique<AccessibilityLabelsBubbleModel>(
       Profile::FromWebUI(web_ui()), web_contents, true /* enable always */);
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 5585a15..0bbc3a8 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -856,7 +856,8 @@
   if (!autofill_driver_factory)
     return false;
   autofill::ContentAutofillDriver* autofill_driver =
-      autofill_driver_factory->DriverForFrame(web_contents->GetMainFrame());
+      autofill_driver_factory->DriverForFrame(
+          web_contents->GetPrimaryMainFrame());
   if (!autofill_driver)
     return false;
   if (!autofill_driver->autofill_manager())
diff --git a/chrome/browser/ui/webui/signin/login_ui_test_utils.cc b/chrome/browser/ui/webui/signin/login_ui_test_utils.cc
index dbcbc79..a0839d13 100644
--- a/chrome/browser/ui/webui/signin/login_ui_test_utils.cc
+++ b/chrome/browser/ui/webui/signin/login_ui_test_utils.cc
@@ -155,7 +155,7 @@
 // Returns the render frame host where Gaia credentials can be filled in.
 content::RenderFrameHost* GetSigninFrame(content::WebContents* web_contents) {
   // Dice displays the Gaia page directly in a tab.
-  return web_contents->GetMainFrame();
+  return web_contents->GetPrimaryMainFrame();
 }
 
 // Waits until the condition is met, by polling.
diff --git a/chrome/browser/ui/webui/signin/signin_utils.cc b/chrome/browser/ui/webui/signin/signin_utils.cc
index 92743d3d..79aa8aff 100644
--- a/chrome/browser/ui/webui/signin/signin_utils.cc
+++ b/chrome/browser/ui/webui/signin/signin_utils.cc
@@ -35,7 +35,7 @@
                                        const std::string& parent_frame_name) {
   content::WebContents* auth_web_contents =
       GetAuthFrameWebContents(web_contents, parent_frame_name);
-  return auth_web_contents ? auth_web_contents->GetMainFrame() : nullptr;
+  return auth_web_contents ? auth_web_contents->GetPrimaryMainFrame() : nullptr;
 }
 
 content::WebContents* GetAuthFrameWebContents(
diff --git a/chrome/browser/ui/webui/web_ui_test_handler.cc b/chrome/browser/ui/webui/web_ui_test_handler.cc
index 96e851c9..19261bea 100644
--- a/chrome/browser/ui/webui/web_ui_test_handler.cc
+++ b/chrome/browser/ui/webui/web_ui_test_handler.cc
@@ -50,7 +50,7 @@
 }
 
 content::RenderFrameHost* WebUITestHandler::GetRenderFrameHostForTest() {
-  return GetWebUI()->GetWebContents()->GetMainFrame();
+  return GetWebUI()->GetWebContents()->GetPrimaryMainFrame();
 }
 
 void WebUITestHandler::TestComplete(
diff --git a/chrome/browser/ui/webui/webui_load_timer.cc b/chrome/browser/ui/webui/webui_load_timer.cc
index 2974205..c4e348d 100644
--- a/chrome/browser/ui/webui/webui_load_timer.cc
+++ b/chrome/browser/ui/webui/webui_load_timer.cc
@@ -49,7 +49,7 @@
 void WebuiLoadTimer::DOMContentLoaded(
     content::RenderFrameHost* render_frame_host) {
   // See comment in DocumentOnLoadCompletedInPrimaryMainFrame.
-  if (!timer_ || render_frame_host != web_contents()->GetMainFrame())
+  if (!timer_ || render_frame_host != web_contents()->GetPrimaryMainFrame())
     return;
   CallUmaHistogramTimes(document_initial_load_uma_id_, timer_->Elapsed());
 }
diff --git a/chrome/browser/ui/webui/webui_webview_browsertest.cc b/chrome/browser/ui/webui/webui_webview_browsertest.cc
index 2de57b7..ce74466 100644
--- a/chrome/browser/ui/webui/webui_webview_browsertest.cc
+++ b/chrome/browser/ui/webui/webui_webview_browsertest.cc
@@ -338,9 +338,11 @@
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GetWebViewEnabledWebUIURL()));
   content::ContextMenuParams params;
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 params);
   EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
 }
 
@@ -357,7 +359,7 @@
   // Flush any pending events to make sure we start with a clean slate.
   content::RunAllPendingInMessageLoop();
   content::RenderViewHost* const render_view_host =
-      embedder_web_contents->GetMainFrame()->GetRenderViewHost();
+      embedder_web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
 
   gfx::NativeView view = embedder_web_contents->GetNativeView();
   view->SetBounds(gfx::Rect(0, 0, 400, 400));
diff --git a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
index 6c66ab6..dc28208 100644
--- a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
+++ b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
@@ -94,14 +94,15 @@
   double old_zoom_level = zoom_controller->GetZoomLevel();
   double new_zoom_level = old_zoom_level + 0.5;
 
-  content::RenderProcessHost* host = web_contents->GetMainFrame()->GetProcess();
+  content::RenderProcessHost* host =
+      web_contents->GetPrimaryMainFrame()->GetProcess();
   {
     content::RenderProcessHostWatcher crash_observer(
         host, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
     host->Shutdown(0);
     crash_observer.Wait();
   }
-  EXPECT_FALSE(web_contents->GetMainFrame()->IsRenderFrameLive());
+  EXPECT_FALSE(web_contents->GetPrimaryMainFrame()->IsRenderFrameLive());
 
   // The following attempt to change the zoom level for a crashed tab should
   // fail.
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index d977a7e..60415bc 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -631,7 +631,7 @@
   content::WebContents* popup_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_NE(opener_contents, popup_contents);
-  content::RenderFrameHost* popup_rfh = popup_contents->GetMainFrame();
+  content::RenderFrameHost* popup_rfh = popup_contents->GetPrimaryMainFrame();
 
   // In the popup, add a visibilitychange handler that ensures we only see the
   // visibilitychange event fired once on tab close.
@@ -705,7 +705,7 @@
 
   // Install a dialog-showing beforeunload handler in the iframe.
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_TRUE(
       ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
 
@@ -726,9 +726,9 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderFrameHost* child =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   EXPECT_EQ(child->GetSiteInstance(),
-            web_contents->GetMainFrame()->GetSiteInstance());
+            web_contents->GetPrimaryMainFrame()->GetSiteInstance());
 
   // Install a dialog-showing beforeunload handler in the iframe.
   EXPECT_TRUE(
diff --git a/chrome/browser/url_param_filter/url_param_filter_browsertest.cc b/chrome/browser/url_param_filter/url_param_filter_browsertest.cc
index c52328b5..aed573f 100644
--- a/chrome/browser/url_param_filter/url_param_filter_browsertest.cc
+++ b/chrome/browser/url_param_filter/url_param_filter_browsertest.cc
@@ -83,9 +83,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -155,9 +157,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -200,9 +204,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -260,9 +266,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -313,9 +321,11 @@
   context_menu_params.link_url = redirect_page;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -368,9 +378,11 @@
   context_menu_params.link_url = redirect_page;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -420,9 +432,11 @@
   context_menu_params.link_url = redirect_page;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -475,9 +489,11 @@
   context_menu_params.link_url = redirect_page;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -532,9 +548,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in New Tab" and wait for the tab to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
 
@@ -575,9 +593,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -619,9 +639,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -676,9 +698,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -731,9 +755,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -779,9 +805,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -858,9 +886,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
@@ -905,9 +935,11 @@
   context_menu_params.link_url = test_root;
 
   // Select "Open Link in Incognito Window" and wait for window to be added.
-  TestRenderViewContextMenu menu(
-      *browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
-      context_menu_params);
+  TestRenderViewContextMenu menu(*browser()
+                                      ->tab_strip_model()
+                                      ->GetActiveWebContents()
+                                      ->GetPrimaryMainFrame(),
+                                 context_menu_params);
   menu.Init();
   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
 
diff --git a/chrome/browser/usb/usb_browsertest.cc b/chrome/browser/usb/usb_browsertest.cc
index 121f939..ae10962 100644
--- a/chrome/browser/usb/usb_browsertest.cc
+++ b/chrome/browser/usb/usb_browsertest.cc
@@ -200,8 +200,10 @@
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
     origin_ = url.DeprecatedGetOriginAsURL();
 
-    RenderFrameHost* render_frame_host =
-        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+    RenderFrameHost* render_frame_host = browser()
+                                             ->tab_strip_model()
+                                             ->GetActiveWebContents()
+                                             ->GetPrimaryMainFrame();
     EXPECT_EQ(origin_, render_frame_host->GetLastCommittedOrigin().GetURL());
   }
 
diff --git a/chrome/browser/usb/web_usb_service_impl.cc b/chrome/browser/usb/web_usb_service_impl.cc
index 0e0a7e4..51d1bb3 100644
--- a/chrome/browser/usb/web_usb_service_impl.cc
+++ b/chrome/browser/usb/web_usb_service_impl.cc
@@ -143,7 +143,7 @@
       content::WebContents::FromRenderFrameHost(render_frame_host_);
   // This class is destroyed on cross-origin navigations and so it is safe to
   // cache these values.
-  origin_ = web_contents->GetMainFrame()->GetLastCommittedOrigin();
+  origin_ = web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   chooser_context_ = UsbChooserContextFactory::GetForProfile(profile);
diff --git a/chrome/browser/vr/test/run_all_perftests.cc b/chrome/browser/vr/test/run_all_perftests.cc
index 8cf623a..7357df9 100644
--- a/chrome/browser/vr/test/run_all_perftests.cc
+++ b/chrome/browser/vr/test/run_all_perftests.cc
@@ -5,6 +5,7 @@
 #include "base/bind.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "chrome/browser/vr/test/vr_gl_test_suite.h"
+#include "ui/gl/gl_display.h"
 
 int main(int argc, char** argv) {
   vr::VrGlTestSuite test_suite(argc, argv);
diff --git a/chrome/browser/vr/test/run_all_pixeltests.cc b/chrome/browser/vr/test/run_all_pixeltests.cc
index 18f3c39..3499090 100644
--- a/chrome/browser/vr/test/run_all_pixeltests.cc
+++ b/chrome/browser/vr/test/run_all_pixeltests.cc
@@ -5,6 +5,7 @@
 #include "base/bind.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "chrome/browser/vr/test/vr_gl_test_suite.h"
+#include "ui/gl/gl_display.h"
 
 int main(int argc, char** argv) {
   vr::VrGlTestSuite test_suite(argc, argv);
diff --git a/chrome/browser/vr/test/vr_gl_test_suite.cc b/chrome/browser/vr/test/vr_gl_test_suite.cc
index 7973361..b0ebfa3 100644
--- a/chrome/browser/vr/test/vr_gl_test_suite.cc
+++ b/chrome/browser/vr/test/vr_gl_test_suite.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/vr/test/vr_gl_test_suite.h"
 
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/test/gl_image_test_support.h"
 
@@ -19,7 +20,7 @@
 void VrGlTestSuite::Initialize() {
   VrTestSuite::Initialize();
 
-  gl::GLImageTestSupport::InitializeGL(absl::nullopt);
+  display_ = gl::GLImageTestSupport::InitializeGL(absl::nullopt);
 
 #if defined(VR_USE_COMMAND_BUFFER)
   // Always enable gpu and oop raster, regardless of platform and denylist.
@@ -31,7 +32,7 @@
 }
 
 void VrGlTestSuite::Shutdown() {
-  gl::GLImageTestSupport::CleanupGL();
+  gl::GLImageTestSupport::CleanupGL(display_);
   vr::VrTestSuite::Shutdown();
 }
 
diff --git a/chrome/browser/vr/test/vr_gl_test_suite.h b/chrome/browser/vr/test/vr_gl_test_suite.h
index 24cdd12..942ca3a 100644
--- a/chrome/browser/vr/test/vr_gl_test_suite.h
+++ b/chrome/browser/vr/test/vr_gl_test_suite.h
@@ -7,6 +7,10 @@
 
 #include "chrome/browser/vr/test/vr_test_suite.h"
 
+namespace gl {
+class GLDisplay;
+}  // namespace gl
+
 namespace vr {
 
 class VrGlTestSuite : public VrTestSuite {
@@ -14,6 +18,9 @@
   VrGlTestSuite(int argc, char** argv);
   void Initialize() override;
   void Shutdown() override;
+
+ private:
+  gl::GLDisplay* display_ = nullptr;
 };
 
 }  // namespace vr
diff --git a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
index 5ef2f9a..1cbbb5e 100644
--- a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
+++ b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
@@ -368,23 +368,25 @@
       permission_manager
           ->GetPermissionStatusForCurrentDocument(
               ContentSettingsType::MEDIASTREAM_MIC,
-              web_contents_->GetMainFrame())
+              web_contents_->GetPrimaryMainFrame())
           .content_setting == CONTENT_SETTING_ALLOW;
   potential_capturing_.video_capture_enabled =
       permission_manager
           ->GetPermissionStatusForCurrentDocument(
               ContentSettingsType::MEDIASTREAM_CAMERA,
-              web_contents_->GetMainFrame())
+              web_contents_->GetPrimaryMainFrame())
           .content_setting == CONTENT_SETTING_ALLOW;
   potential_capturing_.location_access_enabled =
       permission_manager
           ->GetPermissionStatusForCurrentDocument(
-              ContentSettingsType::GEOLOCATION, web_contents_->GetMainFrame())
+              ContentSettingsType::GEOLOCATION,
+              web_contents_->GetPrimaryMainFrame())
           .content_setting == CONTENT_SETTING_ALLOW;
   potential_capturing_.midi_connected =
       permission_manager
           ->GetPermissionStatusForCurrentDocument(
-              ContentSettingsType::MIDI_SYSEX, web_contents_->GetMainFrame())
+              ContentSettingsType::MIDI_SYSEX,
+              web_contents_->GetPrimaryMainFrame())
           .content_setting == CONTENT_SETTING_ALLOW;
 
   indicators_shown_start_time_ = base::Time::Now();
@@ -406,7 +408,7 @@
   // should get a RFH from VRServiceImpl instead of WebContents)
   content_settings::PageSpecificContentSettings* settings =
       content_settings::PageSpecificContentSettings::GetForFrame(
-          web_contents_->GetMainFrame());
+          web_contents_->GetPrimaryMainFrame());
 
   if (settings) {
     active_capturing.location_access_enabled =
diff --git a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
index b2dc5fc..5fc6a1e 100644
--- a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
+++ b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
@@ -435,7 +435,7 @@
   AppId app_id = InstallWebAppFromManifest(browser(), app_url);
   Browser* browser = LaunchWebAppBrowserAndWait(app_id);
   content::RenderFrameHost* render_frame_host =
-      browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+      browser->tab_strip_model()->GetActiveWebContents()->GetPrimaryMainFrame();
   const int render_process_id = render_frame_host->GetProcess()->GetID();
   const int render_frame_id = render_frame_host->GetRoutingID();
 
diff --git a/chrome/browser/web_applications/isolated_app_browsertest.cc b/chrome/browser/web_applications/isolated_app_browsertest.cc
index 3378a48..e6e84ed 100644
--- a/chrome/browser/web_applications/isolated_app_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_app_browsertest.cc
@@ -196,8 +196,10 @@
     return browser()->profile()->GetDefaultStoragePartition();
   }
 
-  content::RenderFrameHost* GetMainFrame(Browser* browser) {
-    return browser->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  content::RenderFrameHost* GetPrimaryMainFrame(Browser* browser) {
+    return browser->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
   }
 };
 
@@ -230,7 +232,7 @@
       NavigateToURLInNewTab(browser(), app_url, WindowOpenDisposition::UNKNOWN);
 
   // The browser shouldn't have opened the app's page.
-  EXPECT_EQ(GetMainFrame(browser())->GetLastCommittedURL(), GURL());
+  EXPECT_EQ(GetPrimaryMainFrame(browser())->GetLastCommittedURL(), GURL());
 
   // The app's frame should belong to an isolated PWA browser window.
   Browser* app_browser = GetBrowserFromFrame(app_frame);
@@ -257,7 +259,7 @@
       NavigateToURLInNewTab(browser(), app_url, WindowOpenDisposition::UNKNOWN);
 
   // The browser shouldn't have opened the app's page.
-  EXPECT_EQ(GetMainFrame(browser())->GetLastCommittedURL(), GURL());
+  EXPECT_EQ(GetPrimaryMainFrame(browser())->GetLastCommittedURL(), GURL());
 
   // The app's frame should belong to an isolated PWA browser window.
   Browser* app_browser = GetBrowserFromFrame(app_frame);
@@ -526,8 +528,9 @@
   // Check that the click resulted in a new isolated web app window that runs in
   // the same isolated non-default storage partition.
   auto* new_app_window = browser_waiter.AwaitAdded();
-  auto* new_app_frame =
-      new_app_window->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+  auto* new_app_frame = new_app_window->tab_strip_model()
+                            ->GetActiveWebContents()
+                            ->GetPrimaryMainFrame();
   auto* new_storage_partition = new_app_frame->GetStoragePartition();
   EXPECT_EQ(new_storage_partition, storage_partition_);
   EXPECT_EQ(new_app_frame->GetWebExposedIsolationLevel(),
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_win_unittest.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_win_unittest.cc
index 9c84862..a4a16eca 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_win_unittest.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_win_unittest.cc
@@ -358,7 +358,7 @@
       shortcut_dir.Append(FILE_PATH_LITERAL("new title.lnk"));
   EXPECT_TRUE(base::PathExists(shortcut_file));
   EXPECT_TRUE(base::win::ResolveShortcutProperties(
-      shortcut_file, ShortcutProperties::IndividualProperties::PROPERTIES_ICON,
+      shortcut_file, ShortcutProperties::PROPERTIES_ICON,
       &shortcut_properties));
   EXPECT_EQ(new_icon_file, shortcut_properties.icon);
 }
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
index 4dea22c4..97e63667 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
@@ -109,7 +109,7 @@
   }
 
   content::RenderFrameHost* RenderFrameHost() const {
-    return web_contents()->GetMainFrame();
+    return web_contents()->GetPrimaryMainFrame();
   }
 
   ExternallyInstalledWebAppPrefs& externally_installed_app_prefs() {
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
index 39a7e73..2f8c5f59 100644
--- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -1695,7 +1695,7 @@
     params.page_url = web_contents->GetVisibleURL();
     params.source_type = ui::MENU_SOURCE_NONE;
     auto menu = std::make_unique<TestRenderViewContextMenu>(
-        *web_contents->GetMainFrame(), params);
+        *web_contents->GetPrimaryMainFrame(), params);
     menu->Init();
     return menu;
   }
diff --git a/chrome/browser/web_applications/web_app_data_retriever.cc b/chrome/browser/web_applications/web_app_data_retriever.cc
index 8ecbfa41..5f521b8 100644
--- a/chrome/browser/web_applications/web_app_data_retriever.cc
+++ b/chrome/browser/web_applications/web_app_data_retriever.cc
@@ -66,8 +66,9 @@
   }
 
   mojo::AssociatedRemote<webapps::mojom::WebPageMetadataAgent> metadata_agent;
-  web_contents->GetMainFrame()->GetRemoteAssociatedInterfaces()->GetInterface(
-      &metadata_agent);
+  web_contents->GetPrimaryMainFrame()
+      ->GetRemoteAssociatedInterfaces()
+      ->GetInterface(&metadata_agent);
 
   // Set the error handler so that we can run |get_web_app_info_callback_| if
   // the WebContents or the RenderFrameHost are destroyed and the connection
diff --git a/chrome/browser/web_applications/web_app_data_retriever_unittest.cc b/chrome/browser/web_applications/web_app_data_retriever_unittest.cc
index 66b21af6..1e00e92b 100644
--- a/chrome/browser/web_applications/web_app_data_retriever_unittest.cc
+++ b/chrome/browser/web_applications/web_app_data_retriever_unittest.cc
@@ -94,7 +94,7 @@
   // Set fake WebPageMetadataAgent to avoid mojo connection errors.
   void SetFakeWebPageMetadataAgent() {
     web_contents()
-        ->GetMainFrame()
+        ->GetPrimaryMainFrame()
         ->GetRemoteAssociatedInterfaces()
         ->OverrideBinderForTesting(
             webapps::mojom::WebPageMetadataAgent::Name_,
@@ -110,7 +110,7 @@
     // TODO(crbug.com/936696): Make WebAppDataRetriever support a change of
     // RenderFrames.
     content::DisableProactiveBrowsingInstanceSwapFor(
-        web_contents()->GetMainFrame());
+        web_contents()->GetPrimaryMainFrame());
   }
 
   void SetRendererWebAppInstallInfo(const WebAppInstallInfo& web_app_info) {
diff --git a/chrome/browser/web_applications/web_app_icon_downloader_unittest.cc b/chrome/browser/web_applications/web_app_icon_downloader_unittest.cc
index fa3fd959..8117f3c 100644
--- a/chrome/browser/web_applications/web_app_icon_downloader_unittest.cc
+++ b/chrome/browser/web_applications/web_app_icon_downloader_unittest.cc
@@ -450,7 +450,7 @@
 
   // Activate the prerendered page.
   content::NavigationSimulator::CreateRendererInitiated(
-      prerender_url, web_contents()->GetMainFrame())
+      prerender_url, web_contents()->GetPrimaryMainFrame())
       ->Commit();
 
   // Ensure prerender activation cancel pending download requests.
diff --git a/chrome/browser/web_applications/web_app_launch_queue.cc b/chrome/browser/web_applications/web_app_launch_queue.cc
index 0e4c7af..22cab7dc 100644
--- a/chrome/browser/web_applications/web_app_launch_queue.cc
+++ b/chrome/browser/web_applications/web_app_launch_queue.cc
@@ -54,15 +54,15 @@
   EntriesBuilder(content::WebContents* web_contents,
                  const GURL& launch_url,
                  size_t expected_number_of_entries)
-      : entry_factory_(web_contents->GetMainFrame()
+      : entry_factory_(web_contents->GetPrimaryMainFrame()
                            ->GetProcess()
                            ->GetStoragePartition()
                            ->GetFileSystemAccessEntryFactory()),
         context_(blink::StorageKey(url::Origin::Create(launch_url)),
                  launch_url,
                  content::GlobalRenderFrameHostId(
-                     web_contents->GetMainFrame()->GetProcess()->GetID(),
-                     web_contents->GetMainFrame()->GetRoutingID())) {
+                     web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
+                     web_contents->GetPrimaryMainFrame()->GetRoutingID())) {
     entries_.reserve(expected_number_of_entries);
   }
 
@@ -178,8 +178,10 @@
                                          const GURL& current_url) {
   DCHECK(registrar_.IsUrlInAppScope(current_url, launch_params.app_id));
   mojo::AssociatedRemote<blink::mojom::WebLaunchService> launch_service;
-  web_contents()->GetMainFrame()->GetRemoteAssociatedInterfaces()->GetInterface(
-      &launch_service);
+  web_contents()
+      ->GetPrimaryMainFrame()
+      ->GetRemoteAssociatedInterfaces()
+      ->GetInterface(&launch_service);
   DCHECK(launch_service);
 
   if (!launch_params.paths.empty() || !launch_params.dir.empty()) {
diff --git a/chrome/browser/web_applications/web_app_notifications_interactive_uitest.cc b/chrome/browser/web_applications/web_app_notifications_interactive_uitest.cc
index 4c0ebf0..e89950d5 100644
--- a/chrome/browser/web_applications/web_app_notifications_interactive_uitest.cc
+++ b/chrome/browser/web_applications/web_app_notifications_interactive_uitest.cc
@@ -60,7 +60,7 @@
 
   content::EvalJsResult AwaitScript(const std::string& script) {
     content::EvalJsResult js_result =
-        content::EvalJs(GetActiveWebContents()->GetMainFrame(), script,
+        content::EvalJs(GetActiveWebContents()->GetPrimaryMainFrame(), script,
                         content::EXECUTE_SCRIPT_DEFAULT_OPTIONS);
 
     // Purges all pending messages to propagate them to notification views.
diff --git a/chrome/browser/web_applications/web_app_url_loader.cc b/chrome/browser/web_applications/web_app_url_loader.cc
index b183f7a..c6be9e3 100644
--- a/chrome/browser/web_applications/web_app_url_loader.cc
+++ b/chrome/browser/web_applications/web_app_url_loader.cc
@@ -80,7 +80,7 @@
   void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                      const GURL& validated_url) override {
     // Ignore subframe loads.
-    if (web_contents()->GetMainFrame() != render_frame_host) {
+    if (web_contents()->GetPrimaryMainFrame() != render_frame_host) {
       return;
     }
 
@@ -111,7 +111,7 @@
                    const GURL& validated_url,
                    int error_code) override {
     // Ignore subframe loads.
-    if (web_contents()->GetMainFrame() != render_frame_host) {
+    if (web_contents()->GetPrimaryMainFrame() != render_frame_host) {
       return;
     }
 
diff --git a/chrome/browser/webauthn/authenticator_request_scheduler_unittest.cc b/chrome/browser/webauthn/authenticator_request_scheduler_unittest.cc
index dd2ec52..c366dab 100644
--- a/chrome/browser/webauthn/authenticator_request_scheduler_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_scheduler_unittest.cc
@@ -27,25 +27,25 @@
 TEST_F(AuthenticatorRequestSchedulerTest,
        SingleWebContents_AtMostOneSimultaneousRequest) {
   auto first_request = AuthenticatorRequestScheduler::CreateRequestDelegate(
-      web_contents()->GetMainFrame());
+      web_contents()->GetPrimaryMainFrame());
   ASSERT_TRUE(first_request);
 
   ASSERT_FALSE(AuthenticatorRequestScheduler::CreateRequestDelegate(
-      web_contents()->GetMainFrame()));
+      web_contents()->GetPrimaryMainFrame()));
 
   first_request.reset();
   ASSERT_TRUE(AuthenticatorRequestScheduler::CreateRequestDelegate(
-      web_contents()->GetMainFrame()));
+      web_contents()->GetPrimaryMainFrame()));
 }
 
 TEST_F(AuthenticatorRequestSchedulerTest,
        TwoWebContents_TwoSimultaneousRequests) {
   auto first_request = AuthenticatorRequestScheduler::CreateRequestDelegate(
-      web_contents()->GetMainFrame());
+      web_contents()->GetPrimaryMainFrame());
 
   auto second_web_contents = CreateTestWebContents();
   auto second_request = AuthenticatorRequestScheduler::CreateRequestDelegate(
-      second_web_contents->GetMainFrame());
+      second_web_contents->GetPrimaryMainFrame());
 
   ASSERT_TRUE(first_request);
   ASSERT_TRUE(second_request);
@@ -70,7 +70,7 @@
   NavigateAndCommit(GURL("https://example.com"));
 
   auto first_request = AuthenticatorRequestScheduler::CreateRequestDelegate(
-      web_contents()->GetMainFrame());
+      web_contents()->GetPrimaryMainFrame());
 
   content::RenderFrameHost* fenced_frame_root =
       content::RenderFrameHostTester::For(main_rfh())->AppendFencedFrame();
diff --git a/chrome/browser/window_placement/window_placement_browsertest.cc b/chrome/browser/window_placement/window_placement_browsertest.cc
index 3bf42eba..49572bc 100644
--- a/chrome/browser/window_placement/window_placement_browsertest.cc
+++ b/chrome/browser/window_placement/window_placement_browsertest.cc
@@ -101,8 +101,10 @@
 
   SetupTwoIframes();
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* local_child = ChildFrameAt(tab->GetMainFrame(), 0);
-  content::RenderFrameHost* remote_child = ChildFrameAt(tab->GetMainFrame(), 1);
+  content::RenderFrameHost* local_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
+  content::RenderFrameHost* remote_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 1);
 
   auto initial_result = std::vector<base::Value>();
   initial_result.emplace_back(801);
@@ -248,8 +250,10 @@
 
   SetupTwoIframes();
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* local_child = ChildFrameAt(tab->GetMainFrame(), 0);
-  content::RenderFrameHost* remote_child = ChildFrameAt(tab->GetMainFrame(), 1);
+  content::RenderFrameHost* local_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
+  content::RenderFrameHost* remote_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 1);
 
   auto* initial_script = R"(
       var screenDetails;
@@ -358,8 +362,10 @@
 
   SetupTwoIframes();
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  content::RenderFrameHost* local_child = ChildFrameAt(tab->GetMainFrame(), 0);
-  content::RenderFrameHost* remote_child = ChildFrameAt(tab->GetMainFrame(), 1);
+  content::RenderFrameHost* local_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
+  content::RenderFrameHost* remote_child =
+      ChildFrameAt(tab->GetPrimaryMainFrame(), 1);
 
   auto* initial_script = R"(
       var screenDetails;
diff --git a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc
index bd0eca5..cde87a1d 100644
--- a/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc
+++ b/chrome/browser/window_placement/window_placement_permission_context_browsertest.cc
@@ -141,7 +141,7 @@
   // Calling getScreenDetails() without a gesture or pre-existing permission
   // will not prompt the user, and leaves the permission in the default "prompt"
   // state.
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_EQ("error",
             EvalJs(tab, kGetScreens, content::EXECUTE_SCRIPT_NO_USER_GESTURE));
   EXPECT_EQ("prompt", EvalJs(tab, kCheckPermission,
@@ -149,17 +149,17 @@
 
   // Calling getScreenDetails() with a gesture will show the prompt, and
   // auto-accept.
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_EQ("granted", EvalJs(tab, kGetScreens));
-  EXPECT_TRUE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_TRUE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
 
   // Calling getScreenDetails() without a gesture, but with pre-existing
   // permission, will succeed, since it does not need to prompt the user.
   WaitForUserActivationExpiry();
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_EQ("granted",
             EvalJs(tab, kGetScreens, content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
 }
 
 // TODO(crbug.com/1290805): Test failing on linux-chromeos-chrome.
@@ -175,7 +175,7 @@
   const GURL url(https_test_server()->GetURL("a.test", "/empty.html"));
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   permissions::PermissionRequestManager* permission_request_manager =
       permissions::PermissionRequestManager::FromWebContents(tab);
 
@@ -186,7 +186,7 @@
   permission_request_manager->Dismiss();
   EXPECT_EQ("prompt", EvalJs(tab, kCheckPermission,
                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
 
   // Deny the prompt after activation expires, expect no activation.
   ExecuteScriptAsync(tab, "getScreenDetails()");
@@ -195,7 +195,7 @@
   permission_request_manager->Deny();
   EXPECT_EQ("denied", EvalJs(tab, kCheckPermission,
                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
 }
 
 // Tests user activation after accepting the permission request.
@@ -203,7 +203,7 @@
   const GURL url(https_test_server()->GetURL("a.test", "/empty.html"));
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   permissions::PermissionRequestManager* permission_request_manager =
       permissions::PermissionRequestManager::FromWebContents(tab);
 
@@ -214,7 +214,7 @@
   permission_request_manager->Accept();
   EXPECT_EQ("granted", EvalJs(tab, kCheckPermission,
                               content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_TRUE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_TRUE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
 }
 
 IN_PROC_BROWSER_TEST_F(WindowPlacementPermissionContextTest,
@@ -223,9 +223,9 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_FALSE(child->GetMainFrame()->HasTransientUserActivation());
 
   permissions::PermissionRequestManager* permission_request_manager =
@@ -238,7 +238,7 @@
   permission_request_manager->Accept();
   EXPECT_EQ("granted", EvalJs(child, kCheckPermission,
                               content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_TRUE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_TRUE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_TRUE(child->GetMainFrame()->HasTransientUserActivation());
 }
 
@@ -251,9 +251,9 @@
   GURL subframe_url(https_test_server()->GetURL("b.test", "/title1.html"));
   content::NavigateIframeToURL(tab, /*iframe_id=*/"test", subframe_url);
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_FALSE(child->GetMainFrame()->HasTransientUserActivation());
 
   permissions::PermissionRequestManager* permission_request_manager =
@@ -286,9 +286,9 @@
   GURL subframe_url(https_test_server()->GetURL("b.test", "/title1.html"));
   content::NavigateIframeToURL(tab, /*iframe_id=*/"test", subframe_url);
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
-  EXPECT_FALSE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_FALSE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_FALSE(child->GetMainFrame()->HasTransientUserActivation());
 
   permissions::PermissionRequestManager* permission_request_manager =
@@ -301,7 +301,7 @@
   permission_request_manager->Accept();
   EXPECT_EQ("granted", EvalJs(child, kCheckPermission,
                               content::EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_TRUE(tab->GetMainFrame()->HasTransientUserActivation());
+  EXPECT_TRUE(tab->GetPrimaryMainFrame()->HasTransientUserActivation());
   EXPECT_TRUE(child->GetMainFrame()->HasTransientUserActivation());
 }
 
@@ -317,7 +317,7 @@
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
 
   EXPECT_EQ(true, EvalJs(tab, R"(window.screen.isExtended)",
@@ -337,7 +337,7 @@
   GURL subframe_url(https_test_server()->GetURL("b.test", "/title1.html"));
   content::NavigateIframeToURL(tab, /*iframe_id=*/"test", subframe_url);
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
 
   EXPECT_EQ(true, EvalJs(tab, R"(window.screen.isExtended)",
@@ -364,7 +364,7 @@
   GURL subframe_url(https_test_server()->GetURL("b.test", "/title1.html"));
   content::NavigateIframeToURL(tab, /*iframe_id=*/"test", subframe_url);
 
-  content::RenderFrameHost* child = ChildFrameAt(tab->GetMainFrame(), 0);
+  content::RenderFrameHost* child = ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
   ASSERT_TRUE(child);
 
   EXPECT_EQ(true, EvalJs(tab, R"(window.screen.isExtended)",
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 649afe42..5d7983a 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1654516623-170a2f603291d43c8f11383ceee31373d67e0c54.profdata
+chrome-linux-main-1654538240-d1fa0534984374c79947cf1a625fa28c9e7476ff.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index a829eb9e..679054d8 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1654494521-c70ec81ef54cdde75476103b08e250345a670987.profdata
+chrome-mac-arm-main-1654538240-ba6a77d553b8e480434013b2b12cc5fae36cde95.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 66ff775..8e74671 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1654516623-882db37a575db514932a72663a70111ddd7b2afe.profdata
+chrome-mac-main-1654538240-404d4de837109c5643d28c6cf7597a9221fc783e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index af02bb6..715d337 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1654516623-07688f2f302a837bad0952eb34c8df1848eae020.profdata
+chrome-win32-main-1654527524-c1bd7dd68f838ec508db4b79f8cb24203ebfb1c0.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 37297bb..9de2d7c 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1654516623-42b4efba5b36a1229087d9ac8f98a38527fc5824.profdata
+chrome-win64-main-1654538240-1541c45f7dec0a44cd5fb3c2bf7040d9af59be1b.profdata
diff --git a/chrome/common/net/x509_certificate_model.cc b/chrome/common/net/x509_certificate_model.cc
index 03e5c19..8c7b7287 100644
--- a/chrome/common/net/x509_certificate_model.cc
+++ b/chrome/common/net/x509_certificate_model.cc
@@ -198,6 +198,80 @@
 constexpr uint8_t kNetscapeRenewalTimeOid[] = {0x60, 0x86, 0x48, 0x01, 0x86,
                                                0xf8, 0x42, 0x01, 0x0f};
 
+// Microsoft OIDs. Do we still need all these?
+//
+// 1.3.6.1.4.1.311.20.2
+constexpr uint8_t kMsCertExtCerttype[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                          0x82, 0x37, 0x14, 0x02};
+
+// 1.3.6.1.4.1.311.21.1
+constexpr uint8_t kMsCertsrvCaVersion[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                           0x82, 0x37, 0x15, 0x01};
+
+// 1.3.6.1.4.1.311.20.2.3
+constexpr uint8_t kMsNtPrincipalName[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                          0x82, 0x37, 0x14, 0x02, 0x03};
+
+// 1.3.6.1.4.1.311.25.1
+constexpr uint8_t kMsNtdsReplication[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                          0x82, 0x37, 0x19, 0x01};
+
+// 1.3.6.1.4.1.311.2.1.21
+constexpr uint8_t kEkuMsIndividualCodeSigning[] = {
+    0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x15};
+
+// 1.3.6.1.4.1.311.2.1.22
+constexpr uint8_t kEkuMsCommercialCodeSigning[] = {
+    0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16};
+
+// 1.3.6.1.4.1.311.10.3.1
+constexpr uint8_t kEkuMsTrustListSigning[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                              0x82, 0x37, 0x0a, 0x03, 0x01};
+
+// 1.3.6.1.4.1.311.10.3.2
+constexpr uint8_t kEkuMsTimeStamping[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                          0x82, 0x37, 0x0a, 0x03, 0x02};
+
+// 1.3.6.1.4.1.311.10.3.3
+constexpr uint8_t kEkuMsServerGatedCrypto[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                               0x82, 0x37, 0x0a, 0x03, 0x03};
+
+// 1.3.6.1.4.1.311.10.3.4
+constexpr uint8_t kEkuMsEncryptingFileSystem[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                                  0x82, 0x37, 0x0a, 0x03, 0x04};
+
+// 1.3.6.1.4.1.311.10.3.4.1
+constexpr uint8_t kEkuMsFileRecovery[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+                                          0x37, 0x0a, 0x03, 0x04, 0x01};
+
+// 1.3.6.1.4.1.311.10.3.5
+constexpr uint8_t kEkuMsWindowsHardwareDriverVerification[] = {
+    0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x05};
+
+// 1.3.6.1.4.1.311.10.3.10
+constexpr uint8_t kEkuMsQualifiedSubordination[] = {
+    0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x0a};
+
+// 1.3.6.1.4.1.311.10.3.11
+constexpr uint8_t kEkuMsKeyRecovery[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                         0x82, 0x37, 0x0a, 0x03, 0x0b};
+
+// 1.3.6.1.4.1.311.10.3.12
+constexpr uint8_t kEkuMsDocumentSigning[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                             0x82, 0x37, 0x0a, 0x03, 0x0c};
+
+// 1.3.6.1.4.1.311.10.3.13
+constexpr uint8_t kEkuMsLifetimeSigning[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                             0x82, 0x37, 0x0a, 0x03, 0x0d};
+
+// 1.3.6.1.4.1.311.20.2.2
+constexpr uint8_t kEkuMsSmartCardLogon[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                            0x82, 0x37, 0x14, 0x02, 0x02};
+
+// 1.3.6.1.4.1.311.21.6
+constexpr uint8_t kEkuMsKeyRecoveryAgent[] = {0x2b, 0x06, 0x01, 0x04, 0x01,
+                                              0x82, 0x37, 0x15, 0x06};
+
 // The certificate viewer may be used to view client certificates, so use the
 // relaxed parsing mode. See crbug.com/770323 and crbug.com/788655.
 constexpr auto kNameStringHandling =
@@ -381,6 +455,34 @@
     {net::der::Input(net::kOCSPSigning), IDS_CERT_EKU_OCSP_SIGNING},
     {net::der::Input(net::kNetscapeServerGatedCrypto),
      IDS_CERT_EKU_NETSCAPE_INTERNATIONAL_STEP_UP},
+
+    // Microsoft oids:
+    {net::der::Input(kMsCertExtCerttype), IDS_CERT_EXT_MS_CERT_TYPE},
+    {net::der::Input(kMsCertsrvCaVersion), IDS_CERT_EXT_MS_CA_VERSION},
+    {net::der::Input(kMsNtPrincipalName), IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME},
+    {net::der::Input(kMsNtdsReplication), IDS_CERT_EXT_MS_NTDS_REPLICATION},
+    {net::der::Input(kEkuMsIndividualCodeSigning),
+     IDS_CERT_EKU_MS_INDIVIDUAL_CODE_SIGNING},
+    {net::der::Input(kEkuMsCommercialCodeSigning),
+     IDS_CERT_EKU_MS_COMMERCIAL_CODE_SIGNING},
+    {net::der::Input(kEkuMsTrustListSigning),
+     IDS_CERT_EKU_MS_TRUST_LIST_SIGNING},
+    {net::der::Input(kEkuMsTimeStamping), IDS_CERT_EKU_MS_TIME_STAMPING},
+    {net::der::Input(kEkuMsServerGatedCrypto),
+     IDS_CERT_EKU_MS_SERVER_GATED_CRYPTO},
+    {net::der::Input(kEkuMsEncryptingFileSystem),
+     IDS_CERT_EKU_MS_ENCRYPTING_FILE_SYSTEM},
+    {net::der::Input(kEkuMsFileRecovery), IDS_CERT_EKU_MS_FILE_RECOVERY},
+    {net::der::Input(kEkuMsWindowsHardwareDriverVerification),
+     IDS_CERT_EKU_MS_WINDOWS_HARDWARE_DRIVER_VERIFICATION},
+    {net::der::Input(kEkuMsQualifiedSubordination),
+     IDS_CERT_EKU_MS_QUALIFIED_SUBORDINATION},
+    {net::der::Input(kEkuMsKeyRecovery), IDS_CERT_EKU_MS_KEY_RECOVERY},
+    {net::der::Input(kEkuMsDocumentSigning), IDS_CERT_EKU_MS_DOCUMENT_SIGNING},
+    {net::der::Input(kEkuMsLifetimeSigning), IDS_CERT_EKU_MS_LIFETIME_SIGNING},
+    {net::der::Input(kEkuMsSmartCardLogon), IDS_CERT_EKU_MS_SMART_CARD_LOGON},
+    {net::der::Input(kEkuMsKeyRecoveryAgent),
+     IDS_CERT_EKU_MS_KEY_RECOVERY_AGENT},
 });
 
 absl::optional<std::string> GetOidText(net::der::Input oid) {
@@ -1343,6 +1445,10 @@
       extension.oid == net::der::Input(kNetscapeLostPasswordURLOid)) {
     return ProcessIA5String(extension.value);
   }
+  // TODO(https://crbug.com/853550): SCT
+  // TODO(mattm): name constraints
+  // TODO(mattm): policy mappings
+  // TODO(mattm): policy constraints
   return ProcessRawBytes(extension.value);
 }
 
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc
index e4df85c..0df4e80 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -905,10 +905,11 @@
   }
 }
 
-std::wstring GetStringResource(int base_message_id) {
+std::wstring GetStringResource(UINT base_message_id) {
   std::wstring localized_string;
 
-  int message_id = base_message_id + GetLanguageSelector().offset();
+  UINT message_id =
+      static_cast<UINT>(base_message_id + GetLanguageSelector().offset());
   const ATLSTRINGRESOURCEIMAGE* image =
       AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), message_id);
   if (image) {
@@ -920,7 +921,7 @@
   return localized_string;
 }
 
-std::wstring GetStringResource(int base_message_id,
+std::wstring GetStringResource(UINT base_message_id,
                                const std::vector<std::wstring>& subst) {
   std::wstring format_string = GetStringResource(base_message_id);
   std::wstring formatted =
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.h b/chrome/credential_provider/gaiacp/gcp_utils.h
index a7125e62..1a0de44f 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils.h
+++ b/chrome/credential_provider/gaiacp/gcp_utils.h
@@ -266,11 +266,11 @@
 void DeleteStartupSentinelForVersion(const std::wstring& version);
 
 // Gets a string resource from the DLL with the given id.
-std::wstring GetStringResource(int base_message_id);
+std::wstring GetStringResource(UINT base_message_id);
 
 // Gets a string resource from the DLL with the given id after replacing the
 // placeholders with the provided substitutions.
-std::wstring GetStringResource(int base_message_id,
+std::wstring GetStringResource(UINT base_message_id,
                                const std::vector<std::wstring>& subst);
 
 // Gets the language selected by the base::win::i18n::LanguageSelector.
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc
index 9a70296..883d032 100644
--- a/chrome/installer/setup/install_worker.cc
+++ b/chrome/installer/setup/install_worker.cc
@@ -297,7 +297,6 @@
       ->set_best_effort(true);
 }
 
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Adds work items to register the Elevation Service with Windows. Only for
 // system level installs.
 void AddElevationServiceWorkItems(const base::FilePath& elevation_service_path,
@@ -320,6 +319,7 @@
   list->AddWorkItem(install_service_work_item);
 }
 
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Adds work items to add the "store-dmtoken" command to Chrome's version key.
 // This method is a no-op if this is anything other than system-level Chrome.
 // The command is used when enrolling Chrome browser instances into enterprise
@@ -428,7 +428,6 @@
   cmd.set_is_web_accessible(true);
   cmd.AddWorkItems(root_key, cmd_key, install_list);
 }
-
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 }  // namespace
@@ -855,12 +854,10 @@
       installer_state.root_key(),
       GetNotificationHelperPath(target_path, new_version), install_list);
 
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (installer_state.system_install()) {
     AddElevationServiceWorkItems(
         GetElevationServicePath(target_path, new_version), install_list);
   }
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING
 
   AddUpdateDowngradeVersionItem(installer_state.root_key(), current_version,
                                 new_version, install_list);
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index d92390e..56768b934 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -601,7 +601,6 @@
     LOG(DFATAL) << "Cannot retrieve the toast activator registry path";
   }
 
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (installer_state.system_install()) {
     if (!InstallServiceWorkItem::DeleteService(
             install_static::GetElevationServiceName(),
@@ -612,7 +611,6 @@
                    << install_static::GetElevationServiceName();
     }
   }
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING
 
   // Delete all Start Menu Internet registrations that refer to this Chrome.
   {
diff --git a/chrome/installer/util/l10n_string_util.cc b/chrome/installer/util/l10n_string_util.cc
index 927557d..4555379 100644
--- a/chrome/installer/util/l10n_string_util.cc
+++ b/chrome/installer/util/l10n_string_util.cc
@@ -62,7 +62,7 @@
   g_translation_delegate = delegate;
 }
 
-std::wstring GetLocalizedString(int base_message_id) {
+std::wstring GetLocalizedString(UINT base_message_id) {
   // Map |base_message_id| to the base id for the current install mode.
   base_message_id = GetBaseMessageIdForMode(base_message_id);
 
@@ -71,7 +71,8 @@
 
   std::wstring localized_string;
 
-  int message_id = base_message_id + GetLanguageSelector().offset();
+  UINT message_id =
+      static_cast<UINT>(base_message_id + GetLanguageSelector().offset());
   const ATLSTRINGRESOURCEIMAGE* image =
       AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), message_id);
   if (image) {
@@ -83,7 +84,7 @@
   return localized_string;
 }
 
-std::wstring GetLocalizedStringF(int base_message_id, const std::wstring& a) {
+std::wstring GetLocalizedStringF(UINT base_message_id, const std::wstring& a) {
   return base::ReplaceStringPlaceholders(GetLocalizedString(base_message_id),
                                          std::vector<std::wstring>(1, a),
                                          nullptr);
diff --git a/chrome/installer/util/l10n_string_util.h b/chrome/installer/util/l10n_string_util.h
index 4b5d737..5a22dac 100644
--- a/chrome/installer/util/l10n_string_util.h
+++ b/chrome/installer/util/l10n_string_util.h
@@ -15,6 +15,8 @@
 
 #include <string>
 
+using UINT = unsigned int;
+
 namespace installer {
 
 class TranslationDelegate {
@@ -36,11 +38,11 @@
 // mapped to a variant that is specific to the current install mode (e.g.,
 // IDS_INBOUND_MDNS_RULE_NAME is mapped to IDS_INBOUND_MDNS_RULE_NAME_CANARY for
 // canary Chrome).
-std::wstring GetLocalizedString(int base_message_id);
+std::wstring GetLocalizedString(UINT base_message_id);
 
 // Returns the localized version of a string (obtained from GetLocalizedString)
 // with $1 replaced with |a|. Additionally, $$ is replaced by $.
-std::wstring GetLocalizedStringF(int base_message_id, const std::wstring& a);
+std::wstring GetLocalizedStringF(UINT base_message_id, const std::wstring& a);
 
 // Given the system language, return a url that points to the localized eula.
 // The empty string is returned on failure.
diff --git a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
index eb27430b1..c580e46 100644
--- a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
+++ b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
@@ -1451,7 +1451,7 @@
       https_server_.GetURL("www.guitarcenter.com", "/cart.html");
   content::RenderFrameHost* fenced_frame_host =
       fenced_frame_test_helper().CreateFencedFrame(
-          web_contents()->GetMainFrame(), fenced_frame_url);
+          web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
   EXPECT_NE(nullptr, fenced_frame_host);
 
   // Do not affect counts.
diff --git a/chrome/services/system_signals/public/cpp/BUILD.gn b/chrome/services/system_signals/public/cpp/BUILD.gn
index 99efa58..5872dc0b 100644
--- a/chrome/services/system_signals/public/cpp/BUILD.gn
+++ b/chrome/services/system_signals/public/cpp/BUILD.gn
@@ -5,12 +5,13 @@
 import("//build/config/features.gni")
 
 source_set("cpp") {
-  public = [ "system_signals_service_host.h" ]
+  public = [ "system_signals_service_host_impl.h" ]
 
-  sources = [ "system_signals_service_host.cc" ]
+  sources = [ "system_signals_service_host_impl.cc" ]
 
   public_deps = [
     "//build",
+    "//components/device_signals/core/common",
     "//components/device_signals/core/common/mojom",
     "//mojo/public/mojom/base",
   ]
diff --git a/chrome/services/system_signals/public/cpp/system_signals_service_host.h b/chrome/services/system_signals/public/cpp/system_signals_service_host.h
deleted file mode 100644
index 08db1ba9..0000000
--- a/chrome/services/system_signals/public/cpp/system_signals_service_host.h
+++ /dev/null
@@ -1,43 +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_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_H_
-#define CHROME_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_H_
-
-#include "build/build_config.h"
-#include "components/device_signals/core/common/mojom/system_signals.mojom-forward.h"
-
-#if BUILDFLAG(IS_WIN)
-#include "mojo/public/cpp/bindings/remote.h"
-#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
-#include <memory>
-#endif
-
-namespace system_signals {
-
-// Class in charge of creating and handling the service's lifecycle. Clients of
-// SystemSignalsService should always go through a common instance of this class
-// to retrieve a service instance.
-class SystemSignalsServiceHost {
- public:
-  SystemSignalsServiceHost();
-  ~SystemSignalsServiceHost();
-
-  SystemSignalsServiceHost(const SystemSignalsServiceHost&) = delete;
-  SystemSignalsServiceHost& operator=(const SystemSignalsServiceHost&) = delete;
-
-  // Returns a pointer to the currently available SystemSignalsService instance.
-  device_signals::mojom::SystemSignalsService* GetService();
-
- private:
-#if BUILDFLAG(IS_WIN)
-  mojom::Remote<device_signals::mojom::SystemSignalsService> remote_service_;
-#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
-  std::unique_ptr<device_signals::mojom::SystemSignalsService> local_service_;
-#endif
-};
-
-}  // namespace system_signals
-
-#endif  // CHROME_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_H_
diff --git a/chrome/services/system_signals/public/cpp/system_signals_service_host.cc b/chrome/services/system_signals/public/cpp/system_signals_service_host_impl.cc
similarity index 87%
rename from chrome/services/system_signals/public/cpp/system_signals_service_host.cc
rename to chrome/services/system_signals/public/cpp/system_signals_service_host_impl.cc
index 5f99d1f5..af8e811 100644
--- a/chrome/services/system_signals/public/cpp/system_signals_service_host.cc
+++ b/chrome/services/system_signals/public/cpp/system_signals_service_host_impl.cc
@@ -18,13 +18,13 @@
 
 namespace system_signals {
 
-SystemSignalsServiceHost::SystemSignalsServiceHost() = default;
-SystemSignalsServiceHost::~SystemSignalsServiceHost() = default;
+SystemSignalsServiceHostImpl::SystemSignalsServiceHostImpl() = default;
+SystemSignalsServiceHostImpl::~SystemSignalsServiceHostImpl() = default;
 
 #if BUILDFLAG(IS_WIN)
 
 device_signals::mojom::SystemSignalsService*
-SystemSignalsServiceHost::GetService() {
+SystemSignalsServiceHostImpl::GetService() {
   // To prevent any impact on Chrome's stability and memory footprint, run
   // this service in its own process on Windows (since it interacts with, e.g.,
   // WMI).
@@ -42,7 +42,7 @@
 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 
 device_signals::mojom::SystemSignalsService*
-SystemSignalsServiceHost::GetService() {
+SystemSignalsServiceHostImpl::GetService() {
   if (!local_service_) {
 #if BUILDFLAG(IS_MAC)
     local_service_ = std::make_unique<MacSystemSignalsService>();
diff --git a/chrome/services/system_signals/public/cpp/system_signals_service_host_impl.h b/chrome/services/system_signals/public/cpp/system_signals_service_host_impl.h
new file mode 100644
index 0000000..c083853
--- /dev/null
+++ b/chrome/services/system_signals/public/cpp/system_signals_service_host_impl.h
@@ -0,0 +1,43 @@
+// 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_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_IMPL_H_
+#define CHROME_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_IMPL_H_
+
+#include "build/build_config.h"
+#include "components/device_signals/core/common/mojom/system_signals.mojom-forward.h"
+#include "components/device_signals/core/common/system_signals_service_host.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "mojo/public/cpp/bindings/remote.h"
+#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+#include <memory>
+#endif
+
+namespace system_signals {
+
+class SystemSignalsServiceHostImpl
+    : public device_signals::SystemSignalsServiceHost {
+ public:
+  SystemSignalsServiceHostImpl();
+  ~SystemSignalsServiceHostImpl();
+
+  SystemSignalsServiceHostImpl(const SystemSignalsServiceHostImpl&) = delete;
+  SystemSignalsServiceHostImpl& operator=(const SystemSignalsServiceHostImpl&) =
+      delete;
+
+  // device_signals::SystemSignalsServiceHost:
+  device_signals::mojom::SystemSignalsService* GetService() override;
+
+ private:
+#if BUILDFLAG(IS_WIN)
+  mojom::Remote<device_signals::mojom::SystemSignalsService> remote_service_;
+#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+  std::unique_ptr<device_signals::mojom::SystemSignalsService> local_service_;
+#endif
+};
+
+}  // namespace system_signals
+
+#endif  // CHROME_SERVICES_SYSTEM_SIGNALS_PUBLIC_CPP_SYSTEM_SIGNALS_SERVICE_HOST_IMPL_H_
diff --git a/chrome/services/system_signals/win/BUILD.gn b/chrome/services/system_signals/win/BUILD.gn
index 6ef9a4d..7066154 100644
--- a/chrome/services/system_signals/win/BUILD.gn
+++ b/chrome/services/system_signals/win/BUILD.gn
@@ -11,8 +11,27 @@
 
   public_deps = [
     "//components/device_signals/core/common/mojom",
+    "//components/device_signals/core/common/win",
     "//mojo/public/mojom/base",
   ]
 
   deps = [ "//base" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "win_system_signals_service_unittest.cc" ]
+
+  deps = [
+    ":win",
+    "//base",
+    "//base/test:test_support",
+    "//components/device_signals/core/common/mojom",
+    "//components/device_signals/core/common/win",
+    "//components/device_signals/core/common/win:test_support",
+    "//mojo/public/mojom/base",
+    "//testing/gmock",
+    "//testing/gtest",
+    "//third_party/abseil-cpp:absl",
+  ]
+}
diff --git a/chrome/services/system_signals/win/win_system_signals_service.cc b/chrome/services/system_signals/win/win_system_signals_service.cc
index ab3848e..46eee95 100644
--- a/chrome/services/system_signals/win/win_system_signals_service.cc
+++ b/chrome/services/system_signals/win/win_system_signals_service.cc
@@ -4,11 +4,28 @@
 
 #include "chrome/services/system_signals/win/win_system_signals_service.h"
 
+#include "base/win/windows_version.h"
+#include "components/device_signals/core/common/win/wmi_client.h"
+#include "components/device_signals/core/common/win/wmi_client_impl.h"
+#include "components/device_signals/core/common/win/wsc_client.h"
+#include "components/device_signals/core/common/win/wsc_client_impl.h"
+
 namespace system_signals {
 
 WinSystemSignalsService::WinSystemSignalsService(
     mojo::PendingReceiver<device_signals::mojom::SystemSignalsService> receiver)
-    : receiver_(this, std::move(receiver)) {}
+    : WinSystemSignalsService(
+          std::move(receiver),
+          std::make_unique<device_signals::WmiClientImpl>(),
+          std::make_unique<device_signals::WscClientImpl>()) {}
+
+WinSystemSignalsService::WinSystemSignalsService(
+    mojo::PendingReceiver<device_signals::mojom::SystemSignalsService> receiver,
+    std::unique_ptr<device_signals::WmiClient> wmi_client,
+    std::unique_ptr<device_signals::WscClient> wsc_client)
+    : receiver_(this, std::move(receiver)),
+      wmi_client_(std::move(wmi_client)),
+      wsc_client_(std::move(wsc_client)) {}
 
 WinSystemSignalsService::~WinSystemSignalsService() = default;
 
@@ -21,14 +38,26 @@
 
 void WinSystemSignalsService::GetAntiVirusSignals(
     GetAntiVirusSignalsCallback callback) {
-  // TODO(b/230471656): Implement this.
+  // WSC is only supported on Win8+, and not server.
+  base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
+  if (os_info && os_info->version_type() != base::win::SUITE_SERVER &&
+      os_info->version() >= base::win::Version::WIN8) {
+    auto response = wsc_client_->GetAntiVirusProducts();
+
+    // TODO(b/229737923): Collect metrics.
+    std::move(callback).Run(std::move(response.av_products));
+    return;
+  }
+
   std::move(callback).Run({});
 }
 
 void WinSystemSignalsService::GetHotfixSignals(
     GetHotfixSignalsCallback callback) {
-  // TODO(b/230471158): Implement this.
-  std::move(callback).Run({});
+  auto response = wmi_client_->GetInstalledHotfixes();
+
+  // TODO(b/229737923): Collect metrics.
+  std::move(callback).Run(std::move(response.hotfixes));
 }
 
 }  // namespace system_signals
diff --git a/chrome/services/system_signals/win/win_system_signals_service.h b/chrome/services/system_signals/win/win_system_signals_service.h
index f03e8d51..2dcdba7c 100644
--- a/chrome/services/system_signals/win/win_system_signals_service.h
+++ b/chrome/services/system_signals/win/win_system_signals_service.h
@@ -5,12 +5,18 @@
 #ifndef CHROME_SERVICES_SYSTEM_SIGNALS_WIN_WIN_SYSTEM_SIGNALS_SERVICE_H_
 #define CHROME_SERVICES_SYSTEM_SIGNALS_WIN_WIN_SYSTEM_SIGNALS_SERVICE_H_
 
+#include <memory>
 #include <vector>
 
 #include "components/device_signals/core/common/mojom/system_signals.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 
+namespace device_signals {
+class WmiClient;
+class WscClient;
+}  // namespace device_signals
+
 namespace system_signals {
 
 class WinSystemSignalsService
@@ -19,6 +25,7 @@
   explicit WinSystemSignalsService(
       mojo::PendingReceiver<device_signals::mojom::SystemSignalsService>
           receiver);
+
   ~WinSystemSignalsService() override;
 
   WinSystemSignalsService(const WinSystemSignalsService&) = delete;
@@ -32,7 +39,19 @@
   void GetHotfixSignals(GetHotfixSignalsCallback callback) override;
 
  private:
+  friend class WinSystemSignalsServiceTest;
+
+  // Constructor that can be used by tests to mock out `wmi_client` and
+  // `wsc_client`.
+  WinSystemSignalsService(
+      mojo::PendingReceiver<device_signals::mojom::SystemSignalsService>
+          receiver,
+      std::unique_ptr<device_signals::WmiClient> wmi_client,
+      std::unique_ptr<device_signals::WscClient> wsc_client);
+
   mojo::Receiver<device_signals::mojom::SystemSignalsService> receiver_;
+  std::unique_ptr<device_signals::WmiClient> wmi_client_;
+  std::unique_ptr<device_signals::WscClient> wsc_client_;
 };
 
 }  // namespace system_signals
diff --git a/chrome/services/system_signals/win/win_system_signals_service_unittest.cc b/chrome/services/system_signals/win/win_system_signals_service_unittest.cc
new file mode 100644
index 0000000..84a7cafd
--- /dev/null
+++ b/chrome/services/system_signals/win/win_system_signals_service_unittest.cc
@@ -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.
+
+#include "chrome/services/system_signals/win/win_system_signals_service.h"
+
+#include <array>
+#include <memory>
+
+#include "base/test/scoped_os_info_override_win.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "components/device_signals/core/common/win/mock_wmi_client.h"
+#include "components/device_signals/core/common/win/mock_wsc_client.h"
+#include "components/device_signals/core/common/win/win_types.h"
+#include "components/device_signals/core/common/win/wmi_client.h"
+#include "components/device_signals/core/common/win/wsc_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+using device_signals::MockWmiClient;
+using device_signals::MockWscClient;
+using testing::Return;
+
+namespace system_signals {
+
+class WinSystemSignalsServiceTest : public testing::Test {
+ protected:
+  WinSystemSignalsServiceTest() {
+    auto wmi_client = std::make_unique<testing::StrictMock<MockWmiClient>>();
+    wmi_client_ = wmi_client.get();
+
+    auto wsc_client = std::make_unique<testing::StrictMock<MockWscClient>>();
+    wsc_client_ = wsc_client.get();
+
+    mojo::PendingReceiver<device_signals::mojom::SystemSignalsService>
+        fake_receiver;
+    win_system_signals_service_ =
+        std::unique_ptr<WinSystemSignalsService>(new WinSystemSignalsService(
+            std::move(fake_receiver), std::move(wmi_client),
+            std::move(wsc_client)));
+  }
+
+  base::test::TaskEnvironment task_environment_;
+  absl::optional<base::test::ScopedOSInfoOverride> os_info_override_;
+
+  MockWmiClient* wmi_client_;
+  MockWscClient* wsc_client_;
+  std::unique_ptr<WinSystemSignalsService> win_system_signals_service_;
+};
+
+// Tests that AV products cannot be retrieve on Win Server environments.
+TEST_F(WinSystemSignalsServiceTest, GetAntiVirusSignals_Server) {
+  std::array<base::test::ScopedOSInfoOverride::Type, 3> server_versions = {
+      base::test::ScopedOSInfoOverride::Type::kWinServer2012R2,
+      base::test::ScopedOSInfoOverride::Type::kWinServer2016,
+      base::test::ScopedOSInfoOverride::Type::kWinServer2022,
+  };
+
+  for (const auto server_version : server_versions) {
+    os_info_override_.emplace(server_version);
+
+    base::test::TestFuture<const std::vector<device_signals::AvProduct>&>
+        future;
+    win_system_signals_service_->GetAntiVirusSignals(future.GetCallback());
+
+    EXPECT_EQ(future.Get().size(), 0U);
+  }
+}
+
+// Tests that AV products are retrieved through WSC on Win8 and above.
+TEST_F(WinSystemSignalsServiceTest, GetAntiVirusSignals_Wsc_Success) {
+  std::array<base::test::ScopedOSInfoOverride::Type, 5> win_versions = {
+      base::test::ScopedOSInfoOverride::Type::kWin81Pro,
+      base::test::ScopedOSInfoOverride::Type::kWin10Pro,
+      base::test::ScopedOSInfoOverride::Type::kWin10Pro21H1,
+      base::test::ScopedOSInfoOverride::Type::kWin11Home,
+      base::test::ScopedOSInfoOverride::Type::kWin11Pro,
+  };
+
+  for (const auto win_version : win_versions) {
+    os_info_override_.emplace(win_version);
+
+    device_signals::AvProduct fake_av_product;
+    fake_av_product.display_name = "some display name";
+    fake_av_product.product_id = "some product id";
+    fake_av_product.state = device_signals::AvProductState::kOn;
+
+    device_signals::WscAvProductsResponse fake_response;
+    fake_response.av_products.push_back(fake_av_product);
+
+    EXPECT_CALL(*wsc_client_, GetAntiVirusProducts())
+        .WillOnce(Return(fake_response));
+
+    base::test::TestFuture<const std::vector<device_signals::AvProduct>&>
+        future;
+    win_system_signals_service_->GetAntiVirusSignals(future.GetCallback());
+
+    const auto& av_products = future.Get();
+    EXPECT_EQ(av_products.size(), fake_response.av_products.size());
+    EXPECT_EQ(av_products[0].product_id,
+              fake_response.av_products[0].product_id);
+  }
+}
+
+// Tests that AV products are not retrieved on Win7.
+TEST_F(WinSystemSignalsServiceTest, GetAntiVirusSignals_Win7) {
+  os_info_override_.emplace(
+      base::test::ScopedOSInfoOverride::Type::kWin7ProSP1);
+
+  base::test::TestFuture<const std::vector<device_signals::AvProduct>&> future;
+  win_system_signals_service_->GetAntiVirusSignals(future.GetCallback());
+
+  EXPECT_EQ(future.Get().size(), 0U);
+}
+
+}  // namespace system_signals
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index d8fc740..569c3dd 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -8141,6 +8141,10 @@
     ]
   }
 
+  if (is_win) {
+    deps += [ "../services/system_signals/win:unit_tests" ]
+  }
+
   if (enable_pdf) {
     sources += [ "../common/pdf_util_unittest.cc" ]
     deps += [ "//pdf:content_restriction" ]
diff --git a/chrome/test/base/mojo_web_ui_browser_test.cc b/chrome/test/base/mojo_web_ui_browser_test.cc
index 63ea05d9..753e2c0 100644
--- a/chrome/test/base/mojo_web_ui_browser_test.cc
+++ b/chrome/test/base/mojo_web_ui_browser_test.cc
@@ -85,7 +85,7 @@
         [&](content::WebUIController* controller,
             mojo::PendingReceiver<web_ui_test::mojom::TestRunner> receiver) {
           content::RenderFrameHost* rfh =
-              controller->web_ui()->GetWebContents()->GetMainFrame();
+              controller->web_ui()->GetWebContents()->GetPrimaryMainFrame();
           this->BindWebUITestRunner(rfh, std::move(receiver));
         }));
   }
@@ -141,13 +141,13 @@
     std::string test_mojo_lite_js =
         ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
             IDR_WEB_UI_TEST_MOJO_LITE_JS);
-    web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+    web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         base::UTF8ToUTF16(test_mojo_lite_js), base::NullCallback());
   } else {
     std::string test_mojo_js =
         ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
             IDR_WEB_UI_TEST_MOJO_JS);
-    web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+    web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
         base::UTF8ToUTF16(test_mojo_js), base::NullCallback());
   }
 }
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index b3accea7..0d728bc 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -150,7 +150,7 @@
     // and this will catch that case.
     auto* contents = dialog->web_contents();
     bool found_disabled_for_testing = false;
-    contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
+    contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
         [](bool* found_disabled_for_testing, content::RenderFrameHost* frame) {
           if (frame->IsBeforeUnloadHangMonitorDisabledForTesting()) {
             *found_disabled_for_testing = true;
@@ -296,7 +296,7 @@
   }
   if (disposition == WindowOpenDisposition::CURRENT_TAB) {
     same_tab_observer.Wait();
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   } else if (web_contents) {
     content::TestNavigationObserver observer(
         web_contents, number_of_navigations,
@@ -305,7 +305,7 @@
     if (!blink::IsRendererDebugURL(url))
       observer.set_expected_initial_url(url);
     observer.Wait();
-    return web_contents->GetMainFrame();
+    return web_contents->GetPrimaryMainFrame();
   }
   EXPECT_TRUE(web_contents)
       << " Unable to wait for navigation to \"" << url.spec() << "\""
@@ -496,7 +496,7 @@
   if (url.is_valid() && contents) {
     base::RunLoop loop;
     auto* storage_partition =
-        contents->GetMainFrame()->GetProcess()->GetStoragePartition();
+        contents->GetPrimaryMainFrame()->GetProcess()->GetStoragePartition();
     net::CookieList cookie_list;
     storage_partition->GetCookieManagerForBrowserProcess()->GetCookieList(
         url, net::CookieOptions::MakeAllInclusive(),
diff --git a/chrome/test/data/extensions/api_test/messaging/connect_fenced_frames/blank_frame.html b/chrome/test/data/extensions/api_test/messaging/connect_fenced_frames/blank_frame.html
new file mode 100644
index 0000000..d03cc429
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/messaging/connect_fenced_frames/blank_frame.html
@@ -0,0 +1,10 @@
+<!--
+ * Copyright (c) 2011 The Chromium Authors. All rights reserved.  Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+
+<!--
+  Blank. Exists so that embedders can execute script in our context using
+  contentWindow.chrome.whatever.
+-->
diff --git a/chrome/test/data/webui/certificate_viewer_ui_test-inl.h b/chrome/test/data/webui/certificate_viewer_ui_test-inl.h
index ce1eb7f0..37c9442 100644
--- a/chrome/test/data/webui/certificate_viewer_ui_test-inl.h
+++ b/chrome/test/data/webui/certificate_viewer_ui_test-inl.h
@@ -49,7 +49,7 @@
   content::WebContents* webui_webcontents = dialog->webui_->GetWebContents();
   EXPECT_TRUE(content::WaitForLoadStop(webui_webcontents));
   content::WebUI* webui = webui_webcontents->GetWebUI();
-  webui_webcontents->GetMainFrame()->SetWebUIProperty(
+  webui_webcontents->GetPrimaryMainFrame()->SetWebUIProperty(
       "expectedUrl", chrome::kChromeUICertificateViewerURL);
   SetWebUIInstance(webui);
 }
diff --git a/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc b/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc
index d5cdc8f4..7786182 100644
--- a/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc
+++ b/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc
@@ -230,7 +230,7 @@
                              : browser()
                                    ->tab_strip_model()
                                    ->GetActiveWebContents()
-                                   ->GetMainFrame();
+                                   ->GetPrimaryMainFrame();
     // We can't use EvalJs with a different world_id to get around CSP
     // restrictions, because Mojo is only exposed to the global world
     // (ISOLATED_WORLD_ID_GLOBAL). So we use |ExecuteScriptAndExtractString| to
@@ -254,7 +254,7 @@
                              : browser()
                                    ->tab_strip_model()
                                    ->GetActiveWebContents()
-                                   ->GetMainFrame();
+                                   ->GetPrimaryMainFrame();
     // We can't use EvalJs with a different world_id to get around CSP
     // restrictions, because Mojo is only exposed to the global world
     // (ISOLATED_WORLD_ID_GLOBAL). So we use |ExecuteScriptAndExtractString| to
@@ -383,7 +383,7 @@
 
   // Bar page gets Bar Mojo API.
   content::RenderFrameHost* bar_frame =
-      ChildFrameAt(web_contents->GetMainFrame(), 0);
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
   ASSERT_EQ(GURL(kBarURL), bar_frame->GetLastCommittedURL());
 
   EXPECT_EQ("bar", EvalStatement("(async () => {"
diff --git a/chrome/test/data/webui/mojo/mojo_web_ui_controller_browsertest.cc b/chrome/test/data/webui/mojo/mojo_web_ui_controller_browsertest.cc
index 643f367..cda29a5 100644
--- a/chrome/test/data/webui/mojo/mojo_web_ui_controller_browsertest.cc
+++ b/chrome/test/data/webui/mojo/mojo_web_ui_controller_browsertest.cc
@@ -265,7 +265,7 @@
 
   content::ScopedAllowRendererCrashes allow;
   content::RenderProcessHostBadMojoMessageWaiter watcher(
-      web_contents->GetMainFrame()->GetProcess());
+      web_contents->GetPrimaryMainFrame()->GetProcess());
 
   // Attempt to bind an interface with no browser binders registered.
   EXPECT_FALSE(content::EvalJs(web_contents,
diff --git a/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js b/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
index 92aac35..c5086ba0 100644
--- a/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/google_assistant_page_test.js
@@ -54,7 +54,7 @@
 
   setup(function() {
     browserProxy = new TestGoogleAssistantBrowserProxy();
-    GoogleAssistantBrowserProxyImpl.instance_ = browserProxy;
+    GoogleAssistantBrowserProxyImpl.setInstance(browserProxy);
 
     PolymerTest.clearBody();
 
@@ -74,7 +74,7 @@
 
   test('toggleAssistant', function() {
     flush();
-    const button = page.$$('#google-assistant-enable');
+    const button = page.shadowRoot.querySelector('#google-assistant-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
@@ -86,12 +86,13 @@
   });
 
   test('toggleAssistantContext', function() {
-    let button = page.$$('#google-assistant-context-enable');
+    let button =
+        page.shadowRoot.querySelector('#google-assistant-context-enable');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     page.setPrefValue('settings.voice_interaction.context.enabled', false);
     flush();
-    button = page.$$('#google-assistant-context-enable');
+    button = page.shadowRoot.querySelector('#google-assistant-context-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
@@ -104,12 +105,13 @@
   });
 
   test('toggleAssistantHotword', function() {
-    let button = page.$$('#google-assistant-hotword-enable');
+    let button =
+        page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     page.setPrefValue('settings.voice_interaction.hotword.enabled', false);
     flush();
-    button = page.$$('#google-assistant-hotword-enable');
+    button = page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
@@ -123,13 +125,14 @@
   });
 
   test('hotwordToggleVisibility', function() {
-    let button = page.$$('#google-assistant-hotword-enable');
+    let button =
+        page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertFalse(!!button);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    button = page.$$('#google-assistant-hotword-enable');
+    button = page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertTrue(!!button);
   });
 
@@ -142,16 +145,18 @@
     });
 
     flush();
-    const button = page.$$('#google-assistant-hotword-enable');
-    const indicator = page.$$('#google-assistant-hotword-enable')
-                          .shadowRoot.querySelector('cr-policy-pref-indicator');
+    const button =
+        page.shadowRoot.querySelector('#google-assistant-hotword-enable');
+    const indicator =
+        page.shadowRoot.querySelector('#google-assistant-hotword-enable')
+            .shadowRoot.querySelector('cr-policy-pref-indicator');
     assertTrue(!!button);
     assertTrue(!!indicator);
     assertTrue(button.disabled);
   });
 
   test('tapOnRetrainVoiceModel', function() {
-    let button = page.$$('#retrain-voice-model');
+    let button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     page.setPrefValue('settings.voice_interaction.hotword.enabled', true);
@@ -159,7 +164,7 @@
         'settings.voice_interaction.activity_control.consent_status',
         ConsentStatus.kActivityControlAccepted);
     flush();
-    button = page.$$('#retrain-voice-model');
+    button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertTrue(!!button);
 
     button.click();
@@ -168,25 +173,25 @@
   });
 
   test('retrainButtonVisibility', function() {
-    let button = page.$$('#retrain-voice-model');
+    let button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
-    button = page.$$('#retrain-voice-model');
+    button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertFalse(!!button);
 
     // Hotword disabled.
     // Button should not be shown.
     page.setPrefValue('settings.voice_interaction.hotword.enabled', false);
     flush();
-    button = page.$$('#retrain-voice-model');
+    button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertFalse(!!button);
 
     // Hotword enabled.
     // Button should be shown.
     page.setPrefValue('settings.voice_interaction.hotword.enabled', true);
     flush();
-    button = page.$$('#retrain-voice-model');
+    button = page.shadowRoot.querySelector('#retrain-voice-model');
     assertTrue(!!button);
   });
 
@@ -203,7 +208,8 @@
     Router.getInstance().navigateTo(routes.GOOGLE_ASSISTANT, params);
 
     const deepLinkElement =
-        page.$$('#retrain-voice-model').shadowRoot.querySelector('cr-button');
+        page.shadowRoot.querySelector('#retrain-voice-model')
+            .shadowRoot.querySelector('cr-button');
     await waitAfterNextRender(deepLinkElement);
     assertEquals(
         deepLinkElement, getDeepActiveElement(),
@@ -211,12 +217,14 @@
   });
 
   test('toggleAssistantNotification', function() {
-    let button = page.$$('#google-assistant-notification-enable');
+    let button =
+        page.shadowRoot.querySelector('#google-assistant-notification-enable');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     page.setPrefValue('settings.voice_interaction.notification.enabled', false);
     flush();
-    button = page.$$('#google-assistant-notification-enable');
+    button =
+        page.shadowRoot.querySelector('#google-assistant-notification-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
@@ -229,12 +237,14 @@
   });
 
   test('toggleAssistantLaunchWithMicOpen', function() {
-    let button = page.$$('#google-assistant-launch-with-mic-open');
+    let button =
+        page.shadowRoot.querySelector('#google-assistant-launch-with-mic-open');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     page.setPrefValue('settings.voice_interaction.launch_with_mic_open', false);
     flush();
-    button = page.$$('#google-assistant-launch-with-mic-open');
+    button =
+        page.shadowRoot.querySelector('#google-assistant-launch-with-mic-open');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
@@ -247,11 +257,11 @@
   });
 
   test('tapOnAssistantSettings', function() {
-    let button = page.$$('#google-assistant-settings');
+    let button = page.shadowRoot.querySelector('#google-assistant-settings');
     assertFalse(!!button);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
-    button = page.$$('#google-assistant-settings');
+    button = page.shadowRoot.querySelector('#google-assistant-settings');
     assertTrue(!!button);
 
     button.click();
@@ -260,13 +270,13 @@
   });
 
   test('assistantDisabledByPolicy', function() {
-    let button = page.$$('#google-assistant-enable');
+    let button = page.shadowRoot.querySelector('#google-assistant-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertFalse(button.checked);
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
-    button = page.$$('#google-assistant-enable');
+    button = page.shadowRoot.querySelector('#google-assistant-enable');
     assertTrue(!!button);
     assertFalse(button.disabled);
     assertTrue(button.checked);
@@ -295,7 +305,7 @@
 
   setup(function() {
     browserProxy = new TestGoogleAssistantBrowserProxy();
-    GoogleAssistantBrowserProxyImpl.instance_ = browserProxy;
+    GoogleAssistantBrowserProxyImpl.setInstance(browserProxy);
 
     PolymerTest.clearBody();
 
@@ -325,29 +335,31 @@
   }
 
   test('hotwordToggleVisibilityWithNoDspHotword', function() {
-    let toggle = page.$$('#google-assistant-hotword-enable');
+    let toggle =
+        page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertFalse(!!toggle);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    toggle = page.$$('#google-assistant-hotword-enable');
+    toggle = page.shadowRoot.querySelector('#google-assistant-hotword-enable');
     assertFalse(!!toggle);
   });
 
   test('dspHotwordDropdownVisibilityWithNoDspHotword', function() {
-    let container = page.$$('#dsp-hotword-container');
+    let container = page.shadowRoot.querySelector('#dsp-hotword-container');
     assertFalse(!!container);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    container = page.$$('#dsp-hotword-container');
+    container = page.shadowRoot.querySelector('#dsp-hotword-container');
     assertTrue(!!container);
   });
 
   test('dspHotwordDropdownIndicatorEnabled', function() {
-    let indicator = page.$$('#hotword-policy-pref-indicator');
+    let indicator =
+        page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertFalse(!!indicator);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
@@ -357,15 +369,16 @@
     });
 
     flush();
-    const dropdown = page.$$('#dsp-hotword-state');
-    indicator = page.$$('#hotword-policy-pref-indicator');
+    const dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
+    indicator = page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertTrue(!!dropdown);
     assertFalse(!!indicator);
     assertFalse(dropdown.hasAttribute('disabled'));
   });
 
   test('dspHotwordDropdownIndicatorDisabled', function() {
-    let indicator = page.$$('#hotword-policy-pref-indicator');
+    let indicator =
+        page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertFalse(!!indicator);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
@@ -375,15 +388,16 @@
     });
 
     flush();
-    const dropdown = page.$$('#dsp-hotword-state');
-    indicator = page.$$('#hotword-policy-pref-indicator');
+    const dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
+    indicator = page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertTrue(!!dropdown);
     assertTrue(!!indicator);
     assertTrue(dropdown.hasAttribute('disabled'));
   });
 
   test('dspHotwordDropdownDisabledForChildUser', function() {
-    let indicator = page.$$('#hotword-policy-pref-indicator');
+    let indicator =
+        page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertFalse(!!indicator);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
@@ -394,21 +408,21 @@
     });
 
     flush();
-    const dropdown = page.$$('#dsp-hotword-state');
-    indicator = page.$$('#hotword-policy-pref-indicator');
+    const dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
+    indicator = page.shadowRoot.querySelector('#hotword-policy-pref-indicator');
     assertTrue(!!dropdown);
     assertTrue(!!indicator);
     assertTrue(dropdown.disabled);
   });
 
   test('dspHotwordDropdownSelection', function() {
-    let dropdown = page.$$('#dsp-hotword-state');
+    let dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertFalse(!!dropdown);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    dropdown = page.$$('#dsp-hotword-state');
+    dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertTrue(!!dropdown);
     assertFalse(dropdown.disabled);
 
@@ -435,13 +449,13 @@
   });
 
   test('dspHotwordDropdownStatus', function() {
-    let dropdown = page.$$('#dsp-hotword-state');
+    let dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertFalse(!!dropdown);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    dropdown = page.$$('#dsp-hotword-state');
+    dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertTrue(!!dropdown);
     assertFalse(dropdown.disabled);
 
@@ -462,13 +476,13 @@
   });
 
   test('dspHotwordDropdownDefaultOnSync', function() {
-    let dropdown = page.$$('#dsp-hotword-state');
+    let dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertFalse(!!dropdown);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    dropdown = page.$$('#dsp-hotword-state');
+    dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertTrue(!!dropdown);
     assertFalse(dropdown.disabled);
     selectValue(dropdown, DspHotwordState.OFF);
@@ -480,13 +494,13 @@
   });
 
   test('dspHotwordDropdownAlwaysOnSync', function() {
-    let dropdown = page.$$('#dsp-hotword-state');
+    let dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertFalse(!!dropdown);
 
     page.setPrefValue('settings.voice_interaction.enabled', true);
     flush();
 
-    dropdown = page.$$('#dsp-hotword-state');
+    dropdown = page.shadowRoot.querySelector('#dsp-hotword-state');
     assertTrue(!!dropdown);
     assertFalse(dropdown.disabled);
     selectValue(dropdown, DspHotwordState.OFF);
diff --git a/chrome/test/data/webui/settings/chromeos/kerberos_accounts_test.js b/chrome/test/data/webui/settings/chromeos/kerberos_accounts_test.js
index dffd2fe8..d5246a9 100644
--- a/chrome/test/data/webui/settings/chromeos/kerberos_accounts_test.js
+++ b/chrome/test/data/webui/settings/chromeos/kerberos_accounts_test.js
@@ -42,14 +42,14 @@
     Router.resetInstanceForTesting(new Router(routes));
 
     browserProxy = new TestKerberosAccountsBrowserProxy();
-    KerberosAccountsBrowserProxyImpl.instance_ = browserProxy;
+    KerberosAccountsBrowserProxyImpl.setInstance(browserProxy);
     PolymerTest.clearBody();
     createDialog();
   });
 
   teardown(function() {
     kerberosAccounts.remove();
-    KerberosAccountsBrowserProxyImpl.instance_ = undefined;
+    KerberosAccountsBrowserProxyImpl.setInstance(undefined);
   });
 
   function createDialog() {
@@ -60,7 +60,7 @@
     kerberosAccounts = document.createElement('settings-kerberos-accounts');
     document.body.appendChild(kerberosAccounts);
 
-    accountList = kerberosAccounts.$$('#account-list');
+    accountList = kerberosAccounts.shadowRoot.querySelector('#account-list');
     assertTrue(!!accountList);
   }
 
@@ -69,7 +69,7 @@
     kerberosAccounts.shadowRoot.querySelectorAll('.more-actions')[accountIndex]
         .click();
     // Click on the given action.
-    kerberosAccounts.$$('cr-action-menu')
+    kerberosAccounts.shadowRoot.querySelector('cr-action-menu')
         .querySelectorAll('button')[moreActionsIndex]
         .click();
   }
@@ -120,12 +120,14 @@
 
   test('AddAccount', function() {
     // The kerberos-add-account-dialog shouldn't be open yet.
-    assertTrue(!kerberosAccounts.$$('kerberos-add-account-dialog'));
+    assertTrue(!kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog'));
 
-    kerberosAccounts.$$('#add-account-button').click();
+    kerberosAccounts.shadowRoot.querySelector('#add-account-button').click();
     flush();
 
-    const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
+    const addDialog = kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals('', addDialog.$.username.value);
   });
@@ -136,7 +138,8 @@
     flush();
 
     // The kerberos-add-account-dialog shouldn't be open yet.
-    assertTrue(!kerberosAccounts.$$('kerberos-add-account-dialog'));
+    assertTrue(!kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog'));
 
     // Click "Sign-In" on an existing account.
     // Note that both accounts have a reauth button, but the first one is
@@ -149,7 +152,8 @@
 
     // Now the kerberos-add-account-dialog should be open with preset
     // username.
-    const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
+    const addDialog = kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals(
         TEST_KERBEROS_ACCOUNTS[Account.SECOND].principalName,
@@ -169,7 +173,8 @@
     await browserProxy.whenCalled('getAccounts');
     await flushTasks();
     flush();
-    const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
+    const addDialog = kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals(principal_name, addDialog.$.username.value);
   });
@@ -180,7 +185,8 @@
     clickMoreActions(Account.FIRST, MoreActions.REFRESH_NOW);
     flush();
 
-    const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
+    const addDialog = kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
     assertEquals(
         TEST_KERBEROS_ACCOUNTS[Account.FIRST].principalName,
@@ -188,7 +194,7 @@
   });
 
   test('RefreshAccountShowsToast', async () => {
-    const toast = kerberosAccounts.$$('#account-toast');
+    const toast = kerberosAccounts.shadowRoot.querySelector('#account-toast');
     assertTrue(!!toast);
     assertFalse(toast.open);
 
@@ -197,16 +203,17 @@
     clickMoreActions(Account.FIRST, MoreActions.REFRESH_NOW);
     flush();
 
-    const addDialog = kerberosAccounts.$$('kerberos-add-account-dialog');
+    const addDialog = kerberosAccounts.shadowRoot.querySelector(
+        'kerberos-add-account-dialog');
     assertTrue(!!addDialog);
-    addDialog.$$('.action-button').click();
+    addDialog.shadowRoot.querySelector('.action-button').click();
     flush();
 
     await onEvent(addDialog, 'close');
     await flushTasks();
     flush();
     assertTrue(toast.open);
-    assertTrue(kerberosAccounts.$$('#account-toast-label')
+    assertTrue(kerberosAccounts.shadowRoot.querySelector('#account-toast-label')
                    .innerHTML.includes('refreshed'));
   });
 
@@ -239,7 +246,7 @@
   });
 
   test('RemoveAccountShowsToast', async () => {
-    const toast = kerberosAccounts.$$('#account-toast');
+    const toast = kerberosAccounts.shadowRoot.querySelector('#account-toast');
     assertTrue(!!toast);
     assertFalse(toast.open);
 
@@ -250,7 +257,7 @@
     await flushTasks();
     flush();
     assertTrue(toast.open);
-    assertTrue(kerberosAccounts.$$('#account-toast-label')
+    assertTrue(kerberosAccounts.shadowRoot.querySelector('#account-toast-label')
                    .innerHTML.includes('removed'));
   });
 
@@ -291,7 +298,8 @@
       // Assert 'Remove' button is disabled iff account is managed.
       accountList[i].querySelector('.more-actions').click();
       const moreActions =
-          kerberosAccounts.$$('cr-action-menu').querySelectorAll('button');
+          kerberosAccounts.shadowRoot.querySelector('cr-action-menu')
+              .querySelectorAll('button');
       const removeAccountButton = moreActions[MoreActions.REMOVE_ACCOUNT];
       assertEquals(
           TEST_KERBEROS_ACCOUNTS[i].isManaged, removeAccountButton.disabled);
@@ -303,23 +311,27 @@
       assertEquals(
           TEST_KERBEROS_ACCOUNTS[i].isManaged, hasRemovalPolicyIndicator);
 
-      kerberosAccounts.$$('cr-action-menu').close();
+      kerberosAccounts.shadowRoot.querySelector('cr-action-menu').close();
     }
   });
 
   test('AddAccountsAllowed', function() {
     assertTrue(loadTimeData.getBoolean('kerberosAddAccountsAllowed'));
     createDialog();
-    assertTrue(!kerberosAccounts.$$('#add-account-policy-indicator'));
-    assertFalse(kerberosAccounts.$$('#add-account-button').disabled);
+    assertTrue(!kerberosAccounts.shadowRoot.querySelector(
+        '#add-account-policy-indicator'));
+    assertFalse(kerberosAccounts.shadowRoot.querySelector('#add-account-button')
+                    .disabled);
   });
 
   test('AddAccountsNotAllowed', function() {
     loadTimeData.overrideValues({kerberosAddAccountsAllowed: false});
     createDialog();
     flush();
-    assertTrue(!!kerberosAccounts.$$('#add-account-policy-indicator'));
-    assertTrue(kerberosAccounts.$$('#add-account-button').disabled);
+    assertTrue(!!kerberosAccounts.shadowRoot.querySelector(
+        '#add-account-policy-indicator'));
+    assertTrue(kerberosAccounts.shadowRoot.querySelector('#add-account-button')
+                   .disabled);
 
     // Reset for further tests.
     loadTimeData.overrideValues({kerberosAddAccountsAllowed: true});
@@ -352,14 +364,14 @@
 
   setup(function() {
     browserProxy = new TestKerberosAccountsBrowserProxy();
-    KerberosAccountsBrowserProxyImpl.instance_ = browserProxy;
+    KerberosAccountsBrowserProxyImpl.setInstance(browserProxy);
     PolymerTest.clearBody();
     createDialog(null);
   });
 
   teardown(function() {
     dialog.remove();
-    KerberosAccountsBrowserProxyImpl.instance_ = undefined;
+    KerberosAccountsBrowserProxyImpl.setInstance(undefined);
   });
 
   function createDialog(presetAccount) {
@@ -392,7 +404,7 @@
     generalError = dialog.$['general-error-message'];
     assertTrue(!!generalError);
 
-    title = dialog.$$('[slot=title]').innerText;
+    title = dialog.shadowRoot.querySelector('[slot=title]').innerText;
     assertTrue(!!title);
   }
 
@@ -414,7 +426,8 @@
   function setConfig(config) {
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     const configElement = advancedConfigDialog.querySelector('#config');
     assertFalse(configElement.disabled);
     configElement.value = config;
@@ -428,7 +441,8 @@
   function assertConfig(config) {
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertEquals(config, advancedConfigDialog.querySelector('#config').value);
     advancedConfigDialog.querySelector('.cancel-button').click();
     flush();
@@ -480,7 +494,8 @@
     assertTrue(TEST_KERBEROS_ACCOUNTS[1].passwordWasRemembered);
     createDialog(TEST_KERBEROS_ACCOUNTS[1]);
 
-    assertTrue(!dialog.$$('#rememberPasswordPolicyIndicator'));
+    assertTrue(
+        !dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
     assertFalse(rememberPassword.disabled);
     assertTrue(rememberPassword.checked);
     assertNotEquals('', password.value);
@@ -492,7 +507,8 @@
     createDialog(TEST_KERBEROS_ACCOUNTS[1]);
     flush();
 
-    assertTrue(!!dialog.$$('#rememberPasswordPolicyIndicator'));
+    assertTrue(
+        !!dialog.shadowRoot.querySelector('#rememberPasswordPolicyIndicator'));
     assertTrue(rememberPassword.disabled);
     assertFalse(rememberPassword.checked);
     assertEquals('', password.value);
@@ -506,7 +522,8 @@
     createDialog(null);
     flush();
 
-    assertFalse(dialog.$$('#rememberPasswordContainer').hidden);
+    assertFalse(
+        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
   });
 
   test('RememberPasswordHiddenOnMgs', function() {
@@ -514,7 +531,8 @@
     createDialog(null);
     flush();
 
-    assertTrue(dialog.$$('#rememberPasswordContainer').hidden);
+    assertTrue(
+        dialog.shadowRoot.querySelector('#rememberPasswordContainer').hidden);
 
     // Reset for further tests.
     loadTimeData.overrideValues({isGuest: false});
@@ -590,12 +608,13 @@
   });
 
   test('AdvancedConfigOpenClose', async () => {
-    assertTrue(!dialog.$$('#advancedConfigDialog'));
+    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
     assertFalse(addDialog.hidden);
     advancedConfigButton.click();
     flush();
 
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertTrue(!!advancedConfigDialog);
     assertTrue(advancedConfigDialog.open);
     assertTrue(addDialog.hidden);
@@ -608,7 +627,7 @@
     await browserProxy.whenCalled('validateConfig');
     flush();
     assertFalse(saveButton.disabled);
-    assertTrue(!dialog.$$('#advancedConfigDialog'));
+    assertTrue(!dialog.shadowRoot.querySelector('#advancedConfigDialog'));
     assertFalse(addDialog.hidden);
     assertTrue(addDialog.open);
   });
@@ -616,7 +635,8 @@
   test('AdvancedConfigurationSaveKeepsConfig', async () => {
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertTrue(!!advancedConfigDialog);
 
     // Change config and save.
@@ -633,7 +653,8 @@
   test('AdvancedConfigurationCancelResetsConfig', function() {
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertTrue(!!advancedConfigDialog);
 
     // Change config and cancel.
@@ -651,7 +672,8 @@
     createDialog(TEST_KERBEROS_ACCOUNTS[2]);
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertTrue(!!advancedConfigDialog);
     assertTrue(
         !!advancedConfigDialog.querySelector('#advancedConfigPolicyIndicator'));
@@ -661,7 +683,8 @@
   test('AdvancedConfigurationValidationError', async () => {
     advancedConfigButton.click();
     flush();
-    const advancedConfigDialog = dialog.$$('#advancedConfigDialog');
+    const advancedConfigDialog =
+        dialog.shadowRoot.querySelector('#advancedConfigDialog');
     assertTrue(!!advancedConfigDialog);
 
     // Cause a validation error.
diff --git a/chrome/test/data/webui/settings/chromeos/kerberos_page_test.js b/chrome/test/data/webui/settings/chromeos/kerberos_page_test.js
index 12025a7..c6c2a95 100644
--- a/chrome/test/data/webui/settings/chromeos/kerberos_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/kerberos_page_test.js
@@ -24,14 +24,14 @@
     Router.resetInstanceForTesting(new Router(routes));
 
     browserProxy = new TestKerberosAccountsBrowserProxy();
-    KerberosAccountsBrowserProxyImpl.instance_ = browserProxy;
+    KerberosAccountsBrowserProxyImpl.setInstance(browserProxy);
     PolymerTest.clearBody();
   });
 
   teardown(function() {
     kerberosPage.remove();
     Router.getInstance().resetRouteForTesting();
-    KerberosAccountsBrowserProxyImpl.instance_ = undefined;
+    KerberosAccountsBrowserProxyImpl.setInstance(undefined);
   });
 
   test('Kerberos Section contains a link to Kerberos Accounts', () => {
diff --git a/chrome/test/payments/payment_request_platform_browsertest_base.cc b/chrome/test/payments/payment_request_platform_browsertest_base.cc
index a206daf7..b01b5e4f 100644
--- a/chrome/test/payments/payment_request_platform_browsertest_base.cc
+++ b/chrome/test/payments/payment_request_platform_browsertest_base.cc
@@ -121,7 +121,7 @@
             std::pair<const std::string&, net::EmbeddedTestServer*>>&
             payment_methods) {
   SetDownloaderAndIgnorePortInOriginComparisonForTestingInFrame(
-      payment_methods, GetActiveWebContents()->GetMainFrame());
+      payment_methods, GetActiveWebContents()->GetPrimaryMainFrame());
 }
 
 void PaymentRequestPlatformBrowserTestBase::OnCanMakePaymentCalled() {
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index ff3e0b3..ad5cc27a 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -772,7 +772,7 @@
                        pending_response_client) override {
     EXPECT_EQ(browser_->tab_strip_model()
                   ->GetActiveWebContents()
-                  ->GetMainFrame()
+                  ->GetPrimaryMainFrame()
                   ->GetNetworkIsolationKey(),
               network_isolation_key);
     mojo::Remote<network::mojom::ResolveHostClient> response_client(
@@ -1243,7 +1243,7 @@
   net::NetworkIsolationKey network_isolation_key =
       browser->tab_strip_model()
           ->GetActiveWebContents()
-          ->GetMainFrame()
+          ->GetPrimaryMainFrame()
           ->GetNetworkIsolationKey();
   network::DnsLookupResult result1 = network::BlockingDnsLookup(
       network_context, kHostPortPair, std::move(params), network_isolation_key);
diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc
index 4842934..fd9aa94 100644
--- a/chrome/test/ppapi/ppapi_test.cc
+++ b/chrome/test/ppapi/ppapi_test.cc
@@ -332,7 +332,7 @@
   RenderViewHost* rvh = browser()
                             ->tab_strip_model()
                             ->GetActiveWebContents()
-                            ->GetMainFrame()
+                            ->GetPrimaryMainFrame()
                             ->GetRenderViewHost();
   auto watcher = content::RenderViewHostTester::CreateInputWatcher(
       rvh, blink::WebInputEvent::Type::kTouchStart);
@@ -343,7 +343,7 @@
   browser()
       ->tab_strip_model()
       ->GetActiveWebContents()
-      ->GetMainFrame()
+      ->GetPrimaryMainFrame()
       ->InsertVisualStateCallback(base::BindOnce(
           [](base::OnceClosure quit_closure, bool result) {
             EXPECT_TRUE(result);
diff --git a/chrome/updater/win/ui/l10n_util.cc b/chrome/updater/win/ui/l10n_util.cc
index 85d8cb8f..abbd822 100644
--- a/chrome/updater/win/ui/l10n_util.cc
+++ b/chrome/updater/win/ui/l10n_util.cc
@@ -47,10 +47,11 @@
 
 }  // namespace
 
-std::wstring GetLocalizedString(int base_message_id) {
+std::wstring GetLocalizedString(UINT base_message_id) {
   // Map `base_message_id` to the base id for the current install mode.
   std::wstring localized_string;
-  int message_id = base_message_id + GetLanguageSelector().offset();
+  UINT message_id =
+      static_cast<UINT>(base_message_id + GetLanguageSelector().offset());
   const ATLSTRINGRESOURCEIMAGE* image =
       AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), message_id);
   if (image) {
@@ -61,13 +62,13 @@
   return localized_string;
 }
 
-std::wstring GetLocalizedStringF(int base_message_id,
+std::wstring GetLocalizedStringF(UINT base_message_id,
                                  const std::wstring& replacement) {
   return GetLocalizedStringF(base_message_id,
                              std::vector<std::wstring>{replacement});
 }
 
-std::wstring GetLocalizedStringF(int base_message_id,
+std::wstring GetLocalizedStringF(UINT base_message_id,
                                  std::vector<std::wstring> replacements) {
   // Replacements start at index 1 because the implementation of
   // ReplaceStringPlaceholders does i+1, so the first placeholder would be `$1`.
diff --git a/chrome/updater/win/ui/l10n_util.h b/chrome/updater/win/ui/l10n_util.h
index 548c1ce..8f3e1f7 100644
--- a/chrome/updater/win/ui/l10n_util.h
+++ b/chrome/updater/win/ui/l10n_util.h
@@ -7,20 +7,22 @@
 
 #include <string>
 
+using UINT = unsigned int;
+
 namespace updater {
 
 // Given the base message id of a string, return the localized string based on
 // the language tag. The string is read from the binary's string table, and the
 // localized message id of the string will be calculated based off of the
 // language offsets defined in updater_installer_strings.h.
-std::wstring GetLocalizedString(int base_message_id);
+std::wstring GetLocalizedString(UINT base_message_id);
 // Returns a formatted version of the localized string in which there is only
 // one replacement.
-std::wstring GetLocalizedStringF(int base_message_id,
+std::wstring GetLocalizedStringF(UINT base_message_id,
                                  const std::wstring& replacement);
 // Multivariatic version of GetLocalizedStringF, which can format multiple
 // arguments.
-std::wstring GetLocalizedStringF(int base_message_id,
+std::wstring GetLocalizedStringF(UINT base_message_id,
                                  std::vector<std::wstring> replacements);
 
 }  // namespace updater
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index 8867f81..538d81f 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -165,6 +165,7 @@
       deps += [
         "//chrome/services/system_signals/win",
         "//chrome/services/util_win:lib",
+        "//components/device_signals/core/common/mojom",
       ]
     }
   }
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc
index 64731cd..3e8313f5 100644
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -41,7 +41,7 @@
 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
 #include "chrome/services/util_win/util_read_icon.h"
 #include "chrome/services/util_win/util_win_impl.h"
-#include "components/device_signals/core/common/mojom/system_signals.mojom.h"
+#include "components/device_signals/core/common/mojom/system_signals.mojom.h"  // nogncheck
 #include "components/services/quarantine/public/mojom/quarantine.mojom.h"  // nogncheck
 #include "components/services/quarantine/quarantine_impl.h"  // nogncheck
 #include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
diff --git a/chromecast/browser/android/cast_content_window_android.cc b/chromecast/browser/android/cast_content_window_android.cc
index 637bb00..186e555d 100644
--- a/chromecast/browser/android/cast_content_window_android.cc
+++ b/chromecast/browser/android/cast_content_window_android.cc
@@ -156,13 +156,6 @@
   }
 }
 
-void CastContentWindowAndroid::NotifyVisibilityChange(
-    VisibilityType visibility_type) {
-  for (auto& observer : observers_) {
-    observer->OnVisibilityChange(visibility_type);
-  }
-}
-
 void CastContentWindowAndroid::RequestMoveOut() {
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_CastContentWindowAndroid_requestMoveOut(env, java_window_);
diff --git a/chromecast/browser/android/cast_content_window_android.h b/chromecast/browser/android/cast_content_window_android.h
index 0a471da6c9..d79f950d 100644
--- a/chromecast/browser/android/cast_content_window_android.h
+++ b/chromecast/browser/android/cast_content_window_android.h
@@ -36,7 +36,6 @@
   void RequestVisibility(VisibilityPriority visibility_priority) override;
   void SetActivityContext(base::Value activity_context) override;
   void SetHostContext(base::Value host_context) override;
-  void NotifyVisibilityChange(VisibilityType visibility_type) override;
   void RequestMoveOut() override;
 
   // Called through JNI.
diff --git a/chromecast/browser/cast_content_window.cc b/chromecast/browser/cast_content_window.cc
index ac6a713a..409cd63 100644
--- a/chromecast/browser/cast_content_window.cc
+++ b/chromecast/browser/cast_content_window.cc
@@ -25,6 +25,16 @@
       gesture_router()->GetBinder());
 }
 
+void CastContentWindow::AddObserver(Observer* observer) {
+  DCHECK(observer);
+  sync_observers_.AddObserver(observer);
+}
+
+void CastContentWindow::RemoveObserver(CastContentWindow::Observer* observer) {
+  DCHECK(observer);
+  sync_observers_.RemoveObserver(observer);
+}
+
 void CastContentWindow::AddObserver(
     mojo::PendingRemote<mojom::CastContentWindowObserver> observer) {
   observers_.Add(std::move(observer));
@@ -48,6 +58,15 @@
   RequestMoveOut();
 }
 
+void CastContentWindow::NotifyVisibilityChange(VisibilityType visibility_type) {
+  for (auto& observer : observers_) {
+    observer->OnVisibilityChange(visibility_type);
+  }
+  for (Observer& observer : sync_observers_) {
+    observer.OnVisibilityChange(visibility_type);
+  }
+}
+
 mojom::MediaControlUi* CastContentWindow::media_controls() {
   return nullptr;
 }
diff --git a/chromecast/browser/cast_content_window.h b/chromecast/browser/cast_content_window.h
index 6a397d9..ac5c060 100644
--- a/chromecast/browser/cast_content_window.h
+++ b/chromecast/browser/cast_content_window.h
@@ -7,6 +7,8 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
 #include "chromecast/browser/cast_web_contents.h"
 #include "chromecast/browser/gesture_router.h"
 #include "chromecast/browser/mojom/cast_content_window.mojom.h"
@@ -29,12 +31,23 @@
 class CastContentWindow : public mojom::CastContentWindow,
                           public mojom::ActivityWindow {
  public:
+  // Synchronous in-process observer for CastContentWindow.
+  class Observer : public base::CheckedObserver {
+   public:
+    virtual void OnVisibilityChange(VisibilityType visibility_type) = 0;
+  };
+
   explicit CastContentWindow(mojom::CastWebViewParamsPtr params);
   ~CastContentWindow() override;
 
   // |cast_web_contents| must outlive the CastContentWindow.
   void SetCastWebContents(CastWebContents* cast_web_contents);
 
+  // Adds an observer that receives the notifications in-process.
+  void AddObserver(Observer* observer);
+  // Removes an observer that would receive the notifications in-process.
+  void RemoveObserver(Observer* observer);
+
   CastWebContents* cast_web_contents() { return cast_web_contents_; }
   GestureRouter* gesture_router() { return &gesture_router_; }
 
@@ -57,7 +70,7 @@
   // Notify the window that its visibility type has changed. This should only
   // ever be called by the window manager.
   // TODO(seantopping): Make this private to the window manager.
-  virtual void NotifyVisibilityChange(VisibilityType visibility_type) = 0;
+  virtual void NotifyVisibilityChange(VisibilityType visibility_type);
 
   // Cast activity or application calls it to request for moving out of the
   // screen.
@@ -89,6 +102,7 @@
   mojo::Receiver<mojom::CastContentWindow> receiver_{this};
   mojo::Receiver<mojom::ActivityWindow> activity_window_receiver_{this};
   mojo::RemoteSet<mojom::CastContentWindowObserver> observers_;
+  base::ObserverList<Observer> sync_observers_;
   base::WeakPtrFactory<CastContentWindow> weak_factory_{this};
 };
 
diff --git a/chromecast/browser/cast_content_window_aura.cc b/chromecast/browser/cast_content_window_aura.cc
index 046af01..db11646 100644
--- a/chromecast/browser/cast_content_window_aura.cc
+++ b/chromecast/browser/cast_content_window_aura.cc
@@ -170,13 +170,6 @@
 
 void CastContentWindowAura::SetHostContext(base::Value host_context) {}
 
-void CastContentWindowAura::NotifyVisibilityChange(
-    VisibilityType visibility_type) {
-  for (auto& observer : observers_) {
-    observer->OnVisibilityChange(visibility_type);
-  }
-}
-
 void CastContentWindowAura::RequestMoveOut() {}
 
 void CastContentWindowAura::OnWindowVisibilityChanged(aura::Window* window,
diff --git a/chromecast/browser/cast_content_window_aura.h b/chromecast/browser/cast_content_window_aura.h
index ae72e954..f0044ab 100644
--- a/chromecast/browser/cast_content_window_aura.h
+++ b/chromecast/browser/cast_content_window_aura.h
@@ -43,7 +43,6 @@
   void RequestVisibility(VisibilityPriority visibility_priority) override;
   void SetActivityContext(base::Value activity_context) override;
   void SetHostContext(base::Value host_context) override;
-  void NotifyVisibilityChange(VisibilityType visibility_type) override;
   void RequestMoveOut() override;
   void EnableTouchInput(bool enabled) override;
   mojom::MediaControlUi* media_controls() override;
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h
index ade7c6a..b75fcea6 100644
--- a/chromecast/browser/cast_web_contents.h
+++ b/chromecast/browser/cast_web_contents.h
@@ -136,6 +136,12 @@
     virtual void InnerContentsCreated(CastWebContents* inner_contents,
                                       CastWebContents* outer_contents) {}
 
+    // Notify the page state changed.
+    virtual void PageStateChanged(PageState page_state) {}
+
+    // Notify the page stopped.
+    virtual void PageStopped(PageState page_state, int32_t error_code) {}
+
     // Sets |cast_web_contents_| to |nullptr| but does not remove the Observer
     // from the ObserverList. Called for each Observer during CastWebContents
     // destruction; we don't use Observe(nullptr) since it would mutate the
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc
index e0934ba5..9710040 100644
--- a/chromecast/browser/cast_web_contents_impl.cc
+++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -864,10 +864,18 @@
     for (auto& observer : observers_) {
       observer->PageStopped(page_state_, last_error_);
     }
+    // Notifies the local observers.
+    for (Observer& observer : sync_observers_) {
+      observer.PageStopped(page_state_, last_error_);
+    }
   } else {
     for (auto& observer : observers_) {
       observer->PageStateChanged(page_state_);
     }
+    // Notifies the local observers.
+    for (Observer& observer : sync_observers_) {
+      observer.PageStateChanged(page_state_);
+    }
   }
   notifying_ = false;
 }
diff --git a/chromecast/browser/webview/cast_content_window_embedded.cc b/chromecast/browser/webview/cast_content_window_embedded.cc
index 2f72867..b965f50 100644
--- a/chromecast/browser/webview/cast_content_window_embedded.cc
+++ b/chromecast/browser/webview/cast_content_window_embedded.cc
@@ -137,13 +137,6 @@
   host_context_ = host_context.Clone();
 }
 
-void CastContentWindowEmbedded::NotifyVisibilityChange(
-    VisibilityType visibility_type) {
-  for (auto& observer : observers_) {
-    observer->OnVisibilityChange(visibility_type);
-  }
-}
-
 void CastContentWindowEmbedded::RequestMoveOut() {}
 
 void CastContentWindowEmbedded::OnWindowDestroyed(aura::Window* window) {
diff --git a/chromecast/browser/webview/cast_content_window_embedded.h b/chromecast/browser/webview/cast_content_window_embedded.h
index 2cb58db..c01581b5 100644
--- a/chromecast/browser/webview/cast_content_window_embedded.h
+++ b/chromecast/browser/webview/cast_content_window_embedded.h
@@ -58,7 +58,6 @@
   void RequestVisibility(VisibilityPriority visibility_priority) override;
   void SetActivityContext(base::Value activity_context) override;
   void SetHostContext(base::Value host_context) override;
-  void NotifyVisibilityChange(VisibilityType visibility_type) override;
   void RequestMoveOut() override;
   void EnableTouchInput(bool enabled) override;
 
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 390a6b9..c4459a5 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -19,7 +19,7 @@
 
 // Enables dark/light mode feature.
 const base::Feature kDarkLightMode{"DarkLightMode",
-                                   base::FEATURE_DISABLED_BY_DEFAULT};
+                                   base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Disables "Office Editing for Docs, Sheets & Slides" component app so handlers
 // won't be registered, making it possible to install another version for
diff --git a/chromeos/dbus/hermes/BUILD.gn b/chromeos/dbus/hermes/BUILD.gn
index 6d61c9c..603e7da 100644
--- a/chromeos/dbus/hermes/BUILD.gn
+++ b/chromeos/dbus/hermes/BUILD.gn
@@ -5,11 +5,14 @@
 assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
 
 component("hermes") {
-  public_deps = [ ":hermes_clients" ]
-  deps = [ ":hermes_fakes" ]
+  public_deps = [
+    ":hermes_clients",
+    ":hermes_fakes",
+  ]
 }
 
 source_set("hermes_clients") {
+  visibility = [ ":*" ]
   defines = [ "IS_HERMES_CLIENT_IMPL" ]
   deps = [
     "//base",
@@ -35,6 +38,7 @@
 }
 
 source_set("hermes_fakes") {
+  visibility = [ ":*" ]
   deps = [
     ":hermes_clients",
     "//base",
diff --git a/chromeos/network/BUILD.gn b/chromeos/network/BUILD.gn
index 856c7ec..bd46372 100644
--- a/chromeos/network/BUILD.gn
+++ b/chromeos/network/BUILD.gn
@@ -185,7 +185,7 @@
   public_deps = [
     ":network",
     "//chromeos/components/onc",
-    "//chromeos/dbus/hermes:hermes_fakes",
+    "//chromeos/dbus/hermes",
     "//dbus",
   ]
   deps = [
@@ -193,7 +193,6 @@
     "//chromeos:test_utils",
     "//chromeos/components/onc:test_support",
     "//chromeos/dbus:test_support",
-    "//chromeos/dbus/hermes:hermes_clients",
     "//chromeos/services/network_config/public/cpp",
     "//chromeos/services/network_config/public/mojom",
     "//components/onc",
@@ -248,8 +247,7 @@
     "//chromeos/components/onc",
     "//chromeos/components/onc:test_support",
     "//chromeos/dbus:test_support",
-    "//chromeos/dbus/hermes:hermes_clients",
-    "//chromeos/dbus/hermes:hermes_fakes",
+    "//chromeos/dbus/hermes",
     "//chromeos/dbus/permission_broker",
     "//chromeos/login/login_state",
     "//components/onc",
diff --git a/components/browser_ui/accessibility/android/BUILD.gn b/components/browser_ui/accessibility/android/BUILD.gn
index 2eed362..855fc96 100644
--- a/components/browser_ui/accessibility/android/BUILD.gn
+++ b/components/browser_ui/accessibility/android/BUILD.gn
@@ -64,6 +64,7 @@
     "java/res/layout/page_zoom_preference.xml",
     "java/res/layout/page_zoom_view.xml",
     "java/res/layout/preference_text_scale.xml",
+    "java/res/values/dimens.xml",
     "java/res/values/styles.xml",
     "java/res/xml/accessibility_preferences.xml",
   ]
diff --git a/components/browser_ui/accessibility/android/java/res/layout/page_zoom_preference.xml b/components/browser_ui/accessibility/android/java/res/layout/page_zoom_preference.xml
index 1f0d124b..ddc6303c 100644
--- a/components/browser_ui/accessibility/android/java/res/layout/page_zoom_preference.xml
+++ b/components/browser_ui/accessibility/android/java/res/layout/page_zoom_preference.xml
@@ -47,25 +47,29 @@
         android:orientation="vertical" >
 
         <ImageView
+            android:id="@+id/page_zoom_preview_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:background="@drawable/ic_business"
             android:importantForAccessibility="no"
-            app:tint="@macro/default_icon_color_accent1"
-            android:background="@drawable/ic_business" />
+            app:tint="@macro/default_icon_color_accent1" />
 
         <TextView
+            android:id="@+id/page_zoom_preview_large_text"
             style="@style/TextAppearance.TextLarge.Primary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/page_zoom_preview_text_title" />
 
         <TextView
+            android:id="@+id/page_zoom_preview_medium_text"
             style="@style/TextAppearance.TextMedium.Primary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/page_zoom_preview_text_summary" />
 
         <TextView
+            android:id="@+id/page_zoom_preview_small_text"
             style="@style/TextAppearance.TextSmall.Secondary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/components/browser_ui/accessibility/android/java/res/values/dimens.xml b/components/browser_ui/accessibility/android/java/res/values/dimens.xml
new file mode 100644
index 0000000..62897bf
--- /dev/null
+++ b/components/browser_ui/accessibility/android/java/res/values/dimens.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+-->
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <dimen name="page_zoom_preview_image_size">24dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediator.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediator.java
index 35eb216..366f848 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediator.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediator.java
@@ -5,6 +5,7 @@
 package org.chromium.components.browser_ui.accessibility;
 
 import static org.chromium.components.browser_ui.accessibility.PageZoomUtils.AVAILABLE_ZOOM_FACTORS;
+import static org.chromium.components.browser_ui.accessibility.PageZoomUtils.PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE;
 import static org.chromium.components.browser_ui.accessibility.PageZoomUtils.convertZoomFactorToSeekBarValue;
 
 import androidx.annotation.NonNull;
@@ -33,6 +34,7 @@
         mModel.set(PageZoomProperties.DECREASE_ZOOM_CALLBACK, this::handleDecreaseClicked);
         mModel.set(PageZoomProperties.INCREASE_ZOOM_CALLBACK, this::handleIncreaseClicked);
         mModel.set(PageZoomProperties.SEEKBAR_CHANGE_CALLBACK, this::handleSeekBarValueChanged);
+        mModel.set(PageZoomProperties.MAXIMUM_SEEK_VALUE, PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE);
     }
 
     /**
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java
index 5559a697..63c5eb7 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java
@@ -77,12 +77,12 @@
         when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22);
         mMediator.setWebContents(mWebContentsMock);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 26, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 124, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
         mMediator.handleDecreaseClicked(null);
         verify(mHostZoomMapMock, times(1).description(DECREASE_ZOOM_FAILURE_NO_JNI))
                 .setZoomLevel(mWebContentsMock, 1.56);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 22, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 107, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
 
         // Verify that when already at the minimum zoom, no value is sent to native code.
         when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(-7.6);
@@ -103,24 +103,24 @@
         when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22);
         mMediator.setWebContents(mWebContentsMock);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 26, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 124, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
         mMediator.handleIncreaseClicked(null);
         verify(mHostZoomMapMock, times(1).description(INCREASE_ZOOM_FAILURE_NO_JNI))
                 .setZoomLevel(mWebContentsMock, 3.07);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 31, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 150, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
 
         // Verify that when already at the maximum zoom, no value is sent to native code.
         when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(8.83);
         mMediator.setWebContents(mWebContentsMock);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 475, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
         mMediator.handleIncreaseClicked(null);
         verify(mHostZoomMapMock, never().description(INCREASE_ZOOM_FAILURE_WITH_JNI))
                 .setZoomLevel(eq(mWebContentsMock),
                         ArgumentMatchers.doubleThat(argument -> argument > 8.83));
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                CURRENT_ZOOM_FAILURE, 475, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
     }
 
     @Test
@@ -129,13 +129,13 @@
         when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22);
         mMediator.setWebContents(mWebContentsMock);
         Assert.assertEquals(
-                CURRENT_ZOOM_FAILURE, 26, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
-        mMediator.handleSeekBarValueChanged(28);
+                CURRENT_ZOOM_FAILURE, 124, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+        mMediator.handleSeekBarValueChanged(133);
         verify(mHostZoomMapMock, times(1).description(SEEKBAR_VALUE_FAILURE_NO_JNI))
                 .setZoomLevel(eq(mWebContentsMock),
                         ArgumentMatchers.doubleThat(
                                 argument -> Math.abs(2.5088 - argument) <= 0.001));
         Assert.assertEquals(
-                SEEKBAR_VALUE_FAILURE, 28, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+                SEEKBAR_VALUE_FAILURE, 133, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE));
     }
 }
\ No newline at end of file
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomPreference.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomPreference.java
index af78024..0c5d1e7 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomPreference.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomPreference.java
@@ -6,6 +6,8 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.SeekBar;
 import android.widget.TextView;
@@ -22,6 +24,19 @@
     private int mInitialValue;
     private TextView mCurrentValueText;
 
+    // Values taken from dimens of text_size_* in //ui/android/java/res/values/dimens.xml
+    private static final float DEFAULT_LARGE_TEXT_SIZE_SP = 16.0f;
+    private static final float DEFAULT_MEDIUM_TEXT_SIZE_SP = 14.0f;
+    private static final float DEFAULT_SMALL_TEXT_SIZE_SP = 12.0f;
+
+    private float mDefaultPreviewImageSize;
+    private ImageView mPreviewImage;
+    private LinearLayout.LayoutParams mPreviewImageParams;
+
+    private TextView mPreviewLargeText;
+    private TextView mPreviewMediumText;
+    private TextView mPreviewSmallText;
+
     public PageZoomPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
 
@@ -39,14 +54,25 @@
         container.setBackground(null);
         container.setPadding(0, top, 0, bot);
 
+        mPreviewLargeText = (TextView) holder.findViewById(R.id.page_zoom_preview_large_text);
+        mPreviewMediumText = (TextView) holder.findViewById(R.id.page_zoom_preview_medium_text);
+        mPreviewSmallText = (TextView) holder.findViewById(R.id.page_zoom_preview_small_text);
+
+        mDefaultPreviewImageSize = getContext().getResources().getDimensionPixelSize(
+                R.dimen.page_zoom_preview_image_size);
+        mPreviewImage = (ImageView) holder.findViewById(R.id.page_zoom_preview_image);
+        mPreviewImageParams =
+                new LinearLayout.LayoutParams(mPreviewImage.getWidth(), mPreviewImage.getHeight());
+
         mCurrentValueText = (TextView) holder.findViewById(R.id.page_zoom_current_value_text);
         mCurrentValueText.setText(
                 getContext().getResources().getString(R.string.page_zoom_factor, 100));
 
         SeekBar currentValueSlider = (SeekBar) holder.findViewById(R.id.page_zoom_slider);
         currentValueSlider.setOnSeekBarChangeListener(this);
+        currentValueSlider.setMax(PageZoomUtils.PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE);
         currentValueSlider.setProgress(mInitialValue);
-        updateText(mInitialValue);
+        updateViewsOnProgressChanged(mInitialValue);
     }
 
     /**
@@ -57,15 +83,35 @@
         mInitialValue = value;
     }
 
-    private void updateText(int progress) {
+    private void updateViewsOnProgressChanged(int progress) {
+        updateZoomPercentageText(progress);
+        updatePreviewWidget(progress);
+    }
+
+    private void updateZoomPercentageText(int progress) {
         mCurrentValueText.setText(getContext().getResources().getString(R.string.page_zoom_factor,
                 Math.round(100 * PageZoomUtils.convertSeekBarValueToZoomLevel(progress))));
     }
 
+    private void updatePreviewWidget(int progress) {
+        float multiplier = (float) PageZoomUtils.convertSeekBarValueToZoomLevel(progress);
+
+        mPreviewLargeText.setTextSize(
+                TypedValue.COMPLEX_UNIT_SP, DEFAULT_LARGE_TEXT_SIZE_SP * multiplier);
+        mPreviewMediumText.setTextSize(
+                TypedValue.COMPLEX_UNIT_SP, DEFAULT_MEDIUM_TEXT_SIZE_SP * multiplier);
+        mPreviewSmallText.setTextSize(
+                TypedValue.COMPLEX_UNIT_SP, DEFAULT_SMALL_TEXT_SIZE_SP * multiplier);
+
+        mPreviewImageParams.width = (int) (mDefaultPreviewImageSize * multiplier);
+        mPreviewImageParams.height = (int) (mDefaultPreviewImageSize * multiplier);
+        mPreviewImage.setLayoutParams(mPreviewImageParams);
+    }
+
     @Override
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-        // Update the zoom percentage text as the slider is updated.
-        updateText(progress);
+        // Update the zoom percentage text and preview widget as the slider is updated.
+        updateViewsOnProgressChanged(progress);
     }
 
     @Override
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomProperties.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomProperties.java
index 6ad2cb8..63ee942 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomProperties.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomProperties.java
@@ -26,9 +26,10 @@
     static final WritableBooleanPropertyKey INCREASE_ZOOM_ENABLED =
             new WritableBooleanPropertyKey();
 
+    static final WritableIntPropertyKey MAXIMUM_SEEK_VALUE = new WritableIntPropertyKey();
     static final WritableIntPropertyKey CURRENT_SEEK_VALUE = new WritableIntPropertyKey();
 
     static final PropertyKey[] ALL_KEYS = {DECREASE_ZOOM_CALLBACK, INCREASE_ZOOM_CALLBACK,
             SEEKBAR_CHANGE_CALLBACK, DECREASE_ZOOM_ENABLED, INCREASE_ZOOM_ENABLED,
-            CURRENT_SEEK_VALUE};
+            MAXIMUM_SEEK_VALUE, CURRENT_SEEK_VALUE};
 }
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java
index be80dee..26de809 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java
@@ -29,10 +29,10 @@
  *
  *        string        factor      level      seek value
  *          25%     |   -7.6    |   0.25    |      0      |
- *          50%     |   -3.8    |   0.50    |      5      |
- *         100%     |    0.0    |   1.00    |     16      |
- *         250%     |   5.03    |   2.50    |     47      |
- *         500%     |   8.83    |   5.00    |    100      |
+ *          50%     |   -3.8    |   0.50    |     25      |
+ *         100%     |    0.0    |   1.00    |    125      |
+ *         250%     |   5.03    |   2.50    |    275      |
+ *         500%     |   8.83    |   5.00    |    475      |
  *
  */
 public class PageZoomUtils {
@@ -45,6 +45,9 @@
     // The default value for zoom that user can change in the accessibility settings page.
     public static final int PAGE_ZOOM_DEFAULT_SEEK_VALUE = convertZoomFactorToSeekBarValue(0.0);
 
+    // The max value for the seek bar to help with rounding effects (not shown to user).
+    public static final int PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE = 475;
+
     // The minimum and maximum zoom values as a percentage (e.g. 25% = 0.25, 500% = 5.0)
     private static final float PAGE_ZOOM_MINIMUM_ZOOM_LEVEL = 0.25f;
     private static final float PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL = 5.00f;
@@ -71,7 +74,7 @@
     public static double convertSeekBarValueToZoomFactor(int newValue) {
         // Zoom levels are from |PAGE_ZOOM_MINIMUM_ZOOM_LEVEL| to |PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL|,
         // and these should map linearly to the seekbar's 0 - 100 range.
-        float seekbarPercent = (float) newValue / 100.0f;
+        float seekbarPercent = (float) newValue / PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE;
         float chosenZoomLevel = PAGE_ZOOM_MINIMUM_ZOOM_LEVEL
                 + ((PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL - PAGE_ZOOM_MINIMUM_ZOOM_LEVEL) * seekbarPercent);
 
@@ -99,7 +102,7 @@
         double zoomLevelPercent = (double) (zoomLevel - PAGE_ZOOM_MINIMUM_ZOOM_LEVEL)
                 / (PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL - PAGE_ZOOM_MINIMUM_ZOOM_LEVEL);
 
-        return (int) (100 * zoomLevelPercent);
+        return (int) (PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE * zoomLevelPercent);
     }
 
     /**
@@ -111,7 +114,7 @@
     public static double convertSeekBarValueToZoomLevel(int newValue) {
         return PAGE_ZOOM_MINIMUM_ZOOM_LEVEL
                 + ((PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL - PAGE_ZOOM_MINIMUM_ZOOM_LEVEL)
-                        * ((float) newValue / 100.0f));
+                        * ((float) newValue / PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE));
     }
 
     /**
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomViewBinder.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomViewBinder.java
index 4c1e2d2..bb5d371d 100644
--- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomViewBinder.java
+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomViewBinder.java
@@ -18,6 +18,9 @@
         if (PageZoomProperties.CURRENT_SEEK_VALUE == propertyKey) {
             ((SeekBar) view.findViewById(R.id.page_zoom_slider))
                     .setProgress(model.get(PageZoomProperties.CURRENT_SEEK_VALUE));
+        } else if (PageZoomProperties.MAXIMUM_SEEK_VALUE == propertyKey) {
+            ((SeekBar) view.findViewById(R.id.page_zoom_slider))
+                    .setMax(model.get(PageZoomProperties.MAXIMUM_SEEK_VALUE));
         } else if (PageZoomProperties.DECREASE_ZOOM_CALLBACK == propertyKey) {
             view.findViewById(R.id.page_zoom_decrease_zoom_button)
                     .setOnClickListener(v
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index 5a8a9b8..3d234d6 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "10.3",
-  "log_list_timestamp": "2022-06-05T12:55:29Z",
+  "version": "10.4",
+  "log_list_timestamp": "2022-06-06T12:54:11Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/desks_storage/core/desk_model.h b/components/desks_storage/core/desk_model.h
index 1b76e10..2bb60d8 100644
--- a/components/desks_storage/core/desk_model.h
+++ b/components/desks_storage/core/desk_model.h
@@ -16,6 +16,7 @@
 
 namespace ash {
 class DeskTemplate;
+enum class DeskTemplateType;
 }
 
 namespace apps {
@@ -168,6 +169,14 @@
   // Whether this model is syncing desk templates to server.
   virtual bool IsSyncing() const = 0;
 
+  // Returns another template that shares the same `name` as the template with
+  // the uuid `uuid`. The `uuid` is used to make sure we are not returning the
+  // current entry itself.
+  virtual ash::DeskTemplate* FindOtherEntryWithName(
+      const std::u16string& name,
+      ash::DeskTemplateType type,
+      const base::GUID& uuid) const = 0;
+
   // Observer registration methods. The model will remove all observers upon
   // destruction automatically.
   void AddObserver(DeskModelObserver* observer);
@@ -180,8 +189,8 @@
   void RemovePolicyDeskTemplates();
 
  protected:
-  // Finds the admin desk template with the given `uuid`. Returns `nullptr` if
-  // none is found.
+  // Finds the admin desk template with the given `uuid`. Returns `nullptr`
+  // if none is found.
   std::unique_ptr<ash::DeskTemplate> GetAdminDeskTemplateByUUID(
       const std::string& uuid) const;
 
diff --git a/components/desks_storage/core/desk_model_wrapper.cc b/components/desks_storage/core/desk_model_wrapper.cc
index a294b35..c4bf2b4 100644
--- a/components/desks_storage/core/desk_model_wrapper.cc
+++ b/components/desks_storage/core/desk_model_wrapper.cc
@@ -148,6 +148,18 @@
   return GetDeskTemplateModel()->IsSyncing();
 }
 
+ash::DeskTemplate* DeskModelWrapper::FindOtherEntryWithName(
+    const std::u16string& name,
+    ash::DeskTemplateType type,
+    const base::GUID& uuid) const {
+  if (type == ash::DeskTemplateType::kTemplate) {
+    return GetDeskTemplateModel()->FindOtherEntryWithName(name, type, uuid);
+  } else {
+    return save_and_recall_desks_model_->FindOtherEntryWithName(name, type,
+                                                                uuid);
+  }
+}
+
 desks_storage::DeskSyncBridge* DeskModelWrapper::GetDeskTemplateModel() const {
   DCHECK(desk_template_model_);
   return desk_template_model_;
diff --git a/components/desks_storage/core/desk_model_wrapper.h b/components/desks_storage/core/desk_model_wrapper.h
index 43c616c..abc6c26 100644
--- a/components/desks_storage/core/desk_model_wrapper.h
+++ b/components/desks_storage/core/desk_model_wrapper.h
@@ -51,6 +51,10 @@
   std::vector<base::GUID> GetAllEntryUuids() const override;
   bool IsReady() const override;
   bool IsSyncing() const override;
+  ash::DeskTemplate* FindOtherEntryWithName(
+      const std::u16string& name,
+      ash::DeskTemplateType type,
+      const base::GUID& uuid) const override;
 
   // Setter method to set `desk_template_model_` to the correct `bridge`.
   void SetDeskSyncBridge(desks_storage::DeskSyncBridge* bridge) {
diff --git a/components/desks_storage/core/desk_model_wrapper_unittests.cc b/components/desks_storage/core/desk_model_wrapper_unittests.cc
index 2355f9f0..f9f137f 100644
--- a/components/desks_storage/core/desk_model_wrapper_unittests.cc
+++ b/components/desks_storage/core/desk_model_wrapper_unittests.cc
@@ -48,8 +48,6 @@
 constexpr char kTemplateFileNameFormat[] = "%s.saveddesk";
 constexpr char kUuidFormat[] = "1c186d5a-502e-49ce-9ee1-00000000000%d";
 constexpr char kTemplateNameFormat[] = "desk_%d";
-constexpr char kDeskOneTemplateDuplicateExpectedName[] = "desk_01 (1)";
-constexpr char kDeskOneTemplateDuplicateTwoExpectedName[] = "desk_01 (2)";
 const std::string kTestUuid1 = base::StringPrintf(kUuidFormat, 1);
 const std::string kTestUuid2 = base::StringPrintf(kUuidFormat, 2);
 const std::string kTestUuid3 = base::StringPrintf(kUuidFormat, 3);
@@ -71,7 +69,7 @@
     "2\",\"title\":\"Example2\"}],\"active_tab_index\":1,\"window_id\":0,"
     "\"display_id\":\"100\",\"pre_minimized_window_state\":\"NORMAL\"}]}}]";
 
-// Search |entry_list| for |entry_query| as a uuid and returns true if
+// Search `entry_list` for `uuid_query` as a uuid and returns true if
 // found, false if not.
 bool FindUuidInUuidList(
     const std::string& uuid_query,
@@ -87,20 +85,6 @@
   return false;
 }
 
-// Takes in a vector of DeskTemplate pointers and a uuid, returns a pointer to
-// the DeskTemplate with matching uuid if found in vector, nullptr if not.
-const ash::DeskTemplate* FindEntryInEntryList(
-    const std::string& uuid_string,
-    const std::vector<const ash::DeskTemplate*>& entries) {
-  base::GUID uuid = base::GUID::ParseLowercase(uuid_string);
-  auto found_entry = std::find_if(entries.begin(), entries.end(),
-                                  [&uuid](const ash::DeskTemplate* entry) {
-                                    return uuid == entry->uuid();
-                                  });
-
-  return found_entry != entries.end() ? *found_entry : nullptr;
-}
-
 // Verifies that the status passed into it is kOk
 void VerifyEntryAddedCorrectly(DeskModel::AddOrUpdateEntryStatus status) {
   EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kOk);
@@ -410,7 +394,7 @@
   model_wrapper_->SetPolicyDeskTemplates("");
 }
 
-TEST_F(DeskModelWrapperTest, CanMarkDuplicateEntryNames) {
+TEST_F(DeskModelWrapperTest, CanDetectDuplicateEntryNames) {
   InitializeBridge();
 
   model_wrapper_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
@@ -429,30 +413,30 @@
   model_wrapper_->AddOrUpdateEntry(std::move(second_dupe_desk_template),
                                    base::BindOnce(&VerifyEntryAddedCorrectly));
 
-  base::RunLoop loop;
-  model_wrapper_->GetAllEntries(base::BindLambdaForTesting(
-      [&](DeskModel::GetAllEntriesStatus status,
-          const std::vector<const ash::DeskTemplate*>& entries) {
-        EXPECT_EQ(status, DeskModel::GetAllEntriesStatus::kOk);
-        EXPECT_EQ(entries.size(), 3ul);
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid1, entries));
-        EXPECT_TRUE(FindUuidInUuidList(dupe_template_uuid, entries));
-        EXPECT_TRUE(FindUuidInUuidList(second_dupe_template_uuid, entries));
-        const ash::DeskTemplate* duplicate_one =
-            FindEntryInEntryList(dupe_template_uuid, entries);
-        EXPECT_NE(duplicate_one, nullptr);
-        EXPECT_EQ(base::UTF16ToUTF8(duplicate_one->template_name()),
-                  kDeskOneTemplateDuplicateExpectedName);
+  EXPECT_TRUE(model_wrapper_->FindOtherEntryWithName(
+      base::UTF8ToUTF16(std::string("desk_01")),
+      ash::DeskTemplateType::kTemplate,
+      base::GUID::ParseCaseInsensitive(dupe_template_uuid)));
+}
 
-        const ash::DeskTemplate* duplicate_two =
-            FindEntryInEntryList(second_dupe_template_uuid, entries);
-        EXPECT_NE(duplicate_two, nullptr);
-        EXPECT_EQ(base::UTF16ToUTF8(duplicate_two->template_name()),
-                  kDeskOneTemplateDuplicateTwoExpectedName);
+TEST_F(DeskModelWrapperTest, CanDetectNoDuplicateEntryNames) {
+  InitializeBridge();
 
-        loop.Quit();
-      }));
-  loop.Run();
+  model_wrapper_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
+                                   base::BindOnce(&VerifyEntryAddedCorrectly));
+  auto dupe_template_uuid = base::StringPrintf(kUuidFormat, 6);
+
+  auto second_template_uuid = base::StringPrintf(kUuidFormat, 7);
+  auto second_desk_template =
+      MakeTestDeskTemplate(second_template_uuid, ash::DeskTemplateSource::kUser,
+                           "desk_02", base::Time::Now());
+  model_wrapper_->AddOrUpdateEntry(std::move(second_desk_template),
+                                   base::BindOnce(&VerifyEntryAddedCorrectly));
+
+  EXPECT_TRUE(model_wrapper_->FindOtherEntryWithName(
+      base::UTF8ToUTF16(std::string("desk_01")),
+      ash::DeskTemplateType::kTemplate,
+      base::GUID::ParseCaseInsensitive(dupe_template_uuid)));
 }
 
 TEST_F(DeskModelWrapperTest, CanGetDeskTemplateEntryByUuid) {
diff --git a/components/desks_storage/core/desk_sync_bridge.cc b/components/desks_storage/core/desk_sync_bridge.cc
index 48db03e..1b52e34 100644
--- a/components/desks_storage/core/desk_sync_bridge.cc
+++ b/components/desks_storage/core/desk_sync_bridge.cc
@@ -1058,15 +1058,6 @@
   entry->set_template_name(
       base::CollapseWhitespace(new_entry->template_name(), true));
 
-  // While we still find duplicate names iterate the duplicate number. i.e.
-  // if there are 4 duplicates of some template name then this iterates until
-  // the current template will be named 5.
-  while (HasUserTemplateWithName(entry->template_name())) {
-    entry->set_template_name(
-        desk_template_util::AppendDuplicateNumberToDuplicateName(
-            entry->template_name()));
-  }
-
   std::unique_ptr<ModelTypeStore::WriteBatch> batch =
       store_->CreateWriteBatch();
 
@@ -1203,6 +1194,16 @@
   return change_processor()->IsTrackingMetadata();
 }
 
+// TODO(zhumatthew): Once desk sync bridge supports save and recall desk type,
+// update this method to search the correct cache for the entry.
+ash::DeskTemplate* DeskSyncBridge::FindOtherEntryWithName(
+    const std::u16string& name,
+    ash::DeskTemplateType type,
+    const base::GUID& uuid) const {
+  return desk_template_util::FindOtherEntryWithName(name, uuid,
+                                                    desk_template_entries_);
+}
+
 sync_pb::WorkspaceDeskSpecifics DeskSyncBridge::ToSyncProto(
     const DeskTemplate* desk_template) {
   apps::AppRegistryCache* cache =
diff --git a/components/desks_storage/core/desk_sync_bridge.h b/components/desks_storage/core/desk_sync_bridge.h
index 97d3248d..fba8b306 100644
--- a/components/desks_storage/core/desk_sync_bridge.h
+++ b/components/desks_storage/core/desk_sync_bridge.h
@@ -29,6 +29,7 @@
 
 namespace ash {
 class DeskTemplate;
+enum class DeskTemplateType;
 }  // namespace ash
 
 namespace desks_storage {
@@ -84,6 +85,11 @@
   // for Workspace Desk model type.
   bool IsSyncing() const override;
 
+  ash::DeskTemplate* FindOtherEntryWithName(
+      const std::u16string& name,
+      ash::DeskTemplateType type,
+      const base::GUID& uuid) const override;
+
   // Other helper methods.
 
   // Converts an ash::DeskTemplate to its corresponding WorkspaceDesk proto.
diff --git a/components/desks_storage/core/desk_sync_bridge_unittest.cc b/components/desks_storage/core/desk_sync_bridge_unittest.cc
index b19c765..626f8cf 100644
--- a/components/desks_storage/core/desk_sync_bridge_unittest.cc
+++ b/components/desks_storage/core/desk_sync_bridge_unittest.cc
@@ -1052,7 +1052,7 @@
   loop.Run();
 }
 
-TEST_F(DeskSyncBridgeTest, AppendsDuplicateMarkingsCorrectly) {
+TEST_F(DeskSyncBridgeTest, CanDetectDuplicateName) {
   InitializeBridge();
 
   AddTwoTemplates();
@@ -1063,16 +1063,23 @@
 
   // The two duplicated templates should be added.
   EXPECT_EQ(4ul, bridge()->GetAllEntryUuids().size());
+  EXPECT_TRUE(bridge()->FindOtherEntryWithName(
+      bridge()->GetUserEntryByUUID(kTestUuid9)->template_name(),
+      bridge()->GetUserEntryByUUID(kTestUuid9)->type(),
+      bridge()->GetUserEntryByUUID(kTestUuid9)->uuid()));
+}
 
-  // Template 8 should be renamed to avoid name collision.
-  EXPECT_EQ("template 1 (1)",
-            base::UTF16ToUTF8(
-                bridge()->GetUserEntryByUUID(kTestUuid8)->template_name()));
+TEST_F(DeskSyncBridgeTest, CanDetectNoDuplicateName) {
+  InitializeBridge();
 
-  // Template 9 should be renamed twice to avoid name collision.
-  EXPECT_EQ("template 1 (2)",
-            base::UTF16ToUTF8(
-                bridge()->GetUserEntryByUUID(kTestUuid9)->template_name()));
+  AddTwoTemplates();
+
+  EXPECT_EQ(2ul, bridge()->GetAllEntryUuids().size());
+
+  EXPECT_FALSE(bridge()->FindOtherEntryWithName(
+      bridge()->GetUserEntryByUUID(kTestUuid1)->template_name(),
+      bridge()->GetUserEntryByUUID(kTestUuid1)->type(),
+      bridge()->GetUserEntryByUUID(kTestUuid1)->uuid()));
 }
 
 TEST_F(DeskSyncBridgeTest, GetEntryByUUIDShouldSucceed) {
diff --git a/components/desks_storage/core/desk_template_util.cc b/components/desks_storage/core/desk_template_util.cc
index c486588..0ac95b6 100644
--- a/components/desks_storage/core/desk_template_util.cc
+++ b/components/desks_storage/core/desk_template_util.cc
@@ -4,21 +4,12 @@
 
 #include "components/desks_storage/core/desk_template_util.h"
 
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
 #include "components/app_constants/constants.h"
 #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
 #include "components/services/app_service/public/cpp/app_types.h"
-#include "third_party/re2/src/re2/re2.h"
 
 namespace {
 
-// Duplicate value format.
-constexpr char kDuplicateNumberFormat[] = "(%d)";
-// Initial duplicate number value.
-constexpr char kInitialDuplicateNumberValue[] = " (1)";
-// Regex used in determining if duplicate name should be incremented.
-constexpr char kDuplicateNumberRegex[] = "\\(([0-9]+)\\)$";
 constexpr char kTestPwaAppId[] = "test_pwa_app_id";
 constexpr char kTestChromeAppId[] = "test_chrome_app_id";
 constexpr char kTestArcAppId[] = "test_arc_app_id";
@@ -40,21 +31,24 @@
   return app;
 }
 
-std::u16string AppendDuplicateNumberToDuplicateName(
-    const std::u16string& duplicate_name_u16) {
-  std::string duplicate_name = base::UTF16ToUTF8(duplicate_name_u16);
-  int found_duplicate_number;
-
-  if (RE2::PartialMatch(duplicate_name, kDuplicateNumberRegex,
-                        &found_duplicate_number)) {
-    RE2::Replace(
-        &duplicate_name, kDuplicateNumberRegex,
-        base::StringPrintf(kDuplicateNumberFormat, found_duplicate_number + 1));
-  } else {
-    duplicate_name.append(kInitialDuplicateNumberValue);
+ash::DeskTemplate* FindOtherEntryWithName(
+    const std::u16string& name,
+    const base::GUID& uuid,
+    const std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>& entries) {
+  auto iter = std::find_if(
+      entries.begin(), entries.end(),
+      [name, uuid](const std::pair<const base::GUID,
+                                   std::unique_ptr<ash::DeskTemplate>>& entry) {
+        // Name duplication is allowed if one of the templates is an admin
+        // template.
+        return (entry.second->uuid() != uuid &&
+                entry.second->template_name() == name &&
+                entry.second->source() != ash::DeskTemplateSource::kPolicy);
+      });
+  if (iter == entries.end()) {
+    return nullptr;
   }
-
-  return base::UTF8ToUTF16(duplicate_name);
+  return iter->second.get();
 }
 
 void PopulateAppRegistryCache(AccountId account_id,
diff --git a/components/desks_storage/core/desk_template_util.h b/components/desks_storage/core/desk_template_util.h
index 05e3d21f..71424375 100644
--- a/components/desks_storage/core/desk_template_util.h
+++ b/components/desks_storage/core/desk_template_util.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "ash/public/cpp/desk_template.h"
 #include "components/account_id/account_id.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 
@@ -14,12 +15,10 @@
 
 namespace desk_template_util {
 
-// Returns a copy of a duplicated name to be stored.  This function works by
-// taking the name to be duplicated and adding a "(1)" to it. If the name
-// already has "(1)" then the number inside of the parenthesis will be
-// incremented.
-std::u16string AppendDuplicateNumberToDuplicateName(
-    const std::u16string& duplicate_name_u16);
+ash::DeskTemplate* FindOtherEntryWithName(
+    const std::u16string& name,
+    const base::GUID& uuid,
+    const std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>& entries);
 
 // Populates the given cache with test app information.
 void PopulateAppRegistryCache(AccountId account_id,
diff --git a/components/desks_storage/core/desk_template_util_unittests.cc b/components/desks_storage/core/desk_template_util_unittests.cc
index 3f18f29..dd0500b 100644
--- a/components/desks_storage/core/desk_template_util_unittests.cc
+++ b/components/desks_storage/core/desk_template_util_unittests.cc
@@ -5,40 +5,59 @@
 #include "components/desks_storage/core/desk_template_util.h"
 
 #include <string>
+#include "base/time/time.h"
 
+#include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace desks_storage {
 
 using DeskTemplateUtilTest = testing::Test;
 
-TEST_F(DeskTemplateUtilTest, AddSequenceNumberForFirstDuplicate) {
-  EXPECT_EQ(u"test (1)",
-            desk_template_util::AppendDuplicateNumberToDuplicateName(u"test"));
+TEST_F(DeskTemplateUtilTest, FindDuplicateEntry) {
+  std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>> entries;
+  const base::GUID& uuid = base::GUID::GenerateRandomV4();
+  auto desk_template = std::make_unique<ash::DeskTemplate>(
+      uuid.AsLowercaseString(), ash::DeskTemplateSource::kUser, "Template 1",
+      base::Time::Now(), ash::DeskTemplateType::kTemplate);
+  entries[uuid] = std::move(desk_template);
+
+  const base::GUID& new_uuid = base::GUID::GenerateRandomV4();
+  auto new_desk_template = std::make_unique<ash::DeskTemplate>(
+      new_uuid.AsLowercaseString(), ash::DeskTemplateSource::kUser,
+      "Template 1", base::Time::Now(), ash::DeskTemplateType::kTemplate);
+  entries[new_uuid] = std::move(new_desk_template);
+  EXPECT_TRUE(
+      desk_template_util::FindOtherEntryWithName(u"Template 1", uuid, entries));
 }
 
-TEST_F(DeskTemplateUtilTest, IncrementSequenceNumberOnSubsequentDuplicate) {
-  EXPECT_EQ(
-      u"test (2)",
-      desk_template_util::AppendDuplicateNumberToDuplicateName(u"test (1)"));
-  EXPECT_EQ(
-      u"test (10)",
-      desk_template_util::AppendDuplicateNumberToDuplicateName(u"test (9)"));
-  EXPECT_EQ(
-      u"test (11)",
-      desk_template_util::AppendDuplicateNumberToDuplicateName(u"test (10)"));
-  EXPECT_EQ(
-      u"test (101)",
-      desk_template_util::AppendDuplicateNumberToDuplicateName(u"test (100)"));
+TEST_F(DeskTemplateUtilTest, FindNoDuplicateEntryInFilledMap) {
+  std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>> entries;
+  const base::GUID& uuid = base::GUID::GenerateRandomV4();
+  auto desk_template = std::make_unique<ash::DeskTemplate>(
+      uuid.AsLowercaseString(), ash::DeskTemplateSource::kUser, "Template 1",
+      base::Time::Now(), ash::DeskTemplateType::kTemplate);
+  entries[uuid] = std::move(desk_template);
+
+  const base::GUID& new_uuid = base::GUID::GenerateRandomV4();
+  auto new_desk_template = std::make_unique<ash::DeskTemplate>(
+      new_uuid.AsLowercaseString(), ash::DeskTemplateSource::kUser,
+      "Template 2", base::Time::Now(), ash::DeskTemplateType::kTemplate);
+  entries[new_uuid] = std::move(new_desk_template);
+  EXPECT_FALSE(
+      desk_template_util::FindOtherEntryWithName(u"Template 1", uuid, entries));
 }
 
-TEST_F(DeskTemplateUtilTest, OnlyIncrementTheLastSequenceNumber) {
-  EXPECT_EQ(u"test (1) (2)",
-            desk_template_util::AppendDuplicateNumberToDuplicateName(
-                u"test (1) (1)"));
-  EXPECT_EQ(u"test (1) (10)",
-            desk_template_util::AppendDuplicateNumberToDuplicateName(
-                u"test (1) (9)"));
+TEST_F(DeskTemplateUtilTest, FindNoDuplicateEntryInAOneElementMap) {
+  std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>> entries;
+  const base::GUID& uuid = base::GUID::GenerateRandomV4();
+  auto desk_template = std::make_unique<ash::DeskTemplate>(
+      uuid.AsLowercaseString(), ash::DeskTemplateSource::kUser, "Template 1",
+      base::Time::Now(), ash::DeskTemplateType::kTemplate);
+
+  entries[uuid] = std::move(desk_template);
+  EXPECT_FALSE(
+      desk_template_util::FindOtherEntryWithName(u"Template 1", uuid, entries));
 }
 
 TEST_F(DeskTemplateUtilTest, PopulateRegistryCacheHasAppInfo) {
diff --git a/components/desks_storage/core/local_desk_data_manager.cc b/components/desks_storage/core/local_desk_data_manager.cc
index 3b48f62..b527c6d8 100644
--- a/components/desks_storage/core/local_desk_data_manager.cc
+++ b/components/desks_storage/core/local_desk_data_manager.cc
@@ -253,16 +253,6 @@
     return;
   }
 
-  // While we still find duplicate names iterate the duplicate number.  i.e.
-  // if there are 4 duplicates of some template name then this iterates
-  // until the current template will be named 5. Perform the conversion to
-  // base::Value here so that AppRegistryCache doesn't run on the IO thread.
-  while (HasEntryWithName(new_entry->template_name(), new_entry->type())) {
-    new_entry->set_template_name(
-        desk_template_util::AppendDuplicateNumberToDuplicateName(
-            new_entry->template_name()));
-  }
-
   apps::AppRegistryCache* cache =
       apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id_);
   DCHECK(cache);
@@ -416,6 +406,14 @@
   return false;
 }
 
+ash::DeskTemplate* LocalDeskDataManager::FindOtherEntryWithName(
+    const std::u16string& name,
+    ash::DeskTemplateType type,
+    const base::GUID& uuid) const {
+  return desk_template_util::FindOtherEntryWithName(name, uuid,
+                                                    saved_desks_list_.at(type));
+}
+
 // static
 void LocalDeskDataManager::SetDisableMaxTemplateLimitForTesting(bool disabled) {
   g_disable_max_template_limit = disabled;
@@ -620,18 +618,6 @@
   std::move(callback).Run(*status_ptr);
 }
 
-bool LocalDeskDataManager::HasEntryWithName(const std::u16string& name,
-                                            ash::DeskTemplateType type) const {
-  return std::find_if(
-             saved_desks_list_.at(type).begin(),
-             saved_desks_list_.at(type).end(),
-             [&name](
-                 const std::pair<const base::GUID,
-                                 std::unique_ptr<ash::DeskTemplate>>& entry) {
-               return entry.second->template_name() == name;
-             }) != saved_desks_list_.at(type).end();
-}
-
 ash::DeskTemplateType LocalDeskDataManager::GetDeskTypeOfUuid(
     const base::GUID uuid) const {
   for (const auto& [desk_type, saved_desk] : saved_desks_list_) {
diff --git a/components/desks_storage/core/local_desk_data_manager.h b/components/desks_storage/core/local_desk_data_manager.h
index 64b7b3f..d9ab73f 100644
--- a/components/desks_storage/core/local_desk_data_manager.h
+++ b/components/desks_storage/core/local_desk_data_manager.h
@@ -70,6 +70,10 @@
   std::vector<base::GUID> GetAllEntryUuids() const override;
   bool IsReady() const override;
   bool IsSyncing() const override;
+  ash::DeskTemplate* FindOtherEntryWithName(
+      const std::u16string& name,
+      ash::DeskTemplateType type,
+      const base::GUID& uuid) const override;
 
   static void SetDisableMaxTemplateLimitForTesting(bool disabled);
   static void SetExcludeSaveAndRecallDeskInMaxEntryCountForTesting(
@@ -135,11 +139,6 @@
           entries_ptr,
       DeskModel::DeleteEntryCallback callback);
 
-  // Returns true if the storage model has an entry of desk type `type` with the
-  // file name `name`.
-  bool HasEntryWithName(const std::u16string& name,
-                        ash::DeskTemplateType type) const;
-
   // Returns the desk type of the `uuid`.
   ash::DeskTemplateType GetDeskTypeOfUuid(const base::GUID uuid) const;
 
diff --git a/components/desks_storage/core/local_desks_data_manager_unittests.cc b/components/desks_storage/core/local_desks_data_manager_unittests.cc
index 7fba0e35e..e1ab1747 100644
--- a/components/desks_storage/core/local_desks_data_manager_unittests.cc
+++ b/components/desks_storage/core/local_desks_data_manager_unittests.cc
@@ -37,12 +37,6 @@
 constexpr char kSaveAndRecallDeskUuidFormat[] =
     "1c186d5a-502e-49ce-9ee1-0000000000%d";
 constexpr char kTemplateNameFormat[] = "desk_%d";
-constexpr char kDeskOneTemplateDuplicateExpectedName[] = "desk_01 (1)";
-constexpr char kDeskOneTemplateDuplicateTwoExpectedName[] = "desk_01 (2)";
-constexpr char kDuplicatePatternMatchingNamedDeskExpectedNameOne[] =
-    "(1) desk_template (1)";
-constexpr char kDuplicatePatternMatchingNamedDeskExpectedNameTwo[] =
-    "(1) desk_template (2)";
 constexpr uint32_t kThreadSafeIterations = 1000;
 
 const base::FilePath kInvalidFilePath = base::FilePath("?");
@@ -94,20 +88,6 @@
   return false;
 }
 
-// Takes in a vector of DeskTemplate pointers and a uuid, returns a pointer to
-// the DeskTemplate with matching uuid if found in vector, nullptr if not.
-const ash::DeskTemplate* FindEntryInEntryList(
-    const std::string& uuid_string,
-    const std::vector<const ash::DeskTemplate*>& entries) {
-  base::GUID uuid = base::GUID::ParseLowercase(uuid_string);
-  auto found_entry = std::find_if(entries.begin(), entries.end(),
-                                  [&uuid](const ash::DeskTemplate* entry) {
-                                    return uuid == entry->uuid();
-                                  });
-
-  return found_entry != entries.end() ? *found_entry : nullptr;
-}
-
 // Verifies that the status passed into it is kOk
 void VerifyEntryAddedCorrectly(DeskModel::AddOrUpdateEntryStatus status) {
   EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kOk);
@@ -448,7 +428,7 @@
   data_manager_->SetPolicyDeskTemplates("");
 }
 
-TEST_F(LocalDeskDataManagerTest, CanMarkDuplicateEntryNames) {
+TEST_F(LocalDeskDataManagerTest, CanDetectDuplicateEntryNames) {
   data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
                                   base::BindOnce(&VerifyEntryAddedCorrectly));
   data_manager_->AddOrUpdateEntry(
@@ -459,68 +439,24 @@
       std::move(sample_desk_template_one_duplicate_two_),
       base::BindOnce(&VerifyEntryAddedCorrectly));
 
-  base::RunLoop loop;
-  data_manager_->GetAllEntries(base::BindLambdaForTesting(
-      [&](DeskModel::GetAllEntriesStatus status,
-          const std::vector<const ash::DeskTemplate*>& entries) {
-        EXPECT_EQ(status, DeskModel::GetAllEntriesStatus::kOk);
-        EXPECT_EQ(entries.size(), 3ul);
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid1, entries));
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid5, entries));
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid6, entries));
-
-        const ash::DeskTemplate* duplicate_one =
-            FindEntryInEntryList(kTestUuid5, entries);
-        EXPECT_NE(duplicate_one, nullptr);
-        EXPECT_EQ(base::UTF16ToUTF8(duplicate_one->template_name()),
-                  std::string(kDeskOneTemplateDuplicateExpectedName));
-
-        const ash::DeskTemplate* duplicate_two =
-            FindEntryInEntryList(kTestUuid6, entries);
-        EXPECT_NE(duplicate_two, nullptr);
-        EXPECT_EQ(base::UTF16ToUTF8(duplicate_two->template_name()),
-                  std::string(kDeskOneTemplateDuplicateTwoExpectedName));
-        loop.Quit();
-      }));
-  loop.Run();
+  EXPECT_TRUE(data_manager_->FindOtherEntryWithName(
+      base::UTF8ToUTF16(std::string("desk_01")),
+      ash::DeskTemplateType::kTemplate,
+      base::GUID::ParseCaseInsensitive(kTestUuid1)));
+  task_environment_.RunUntilIdle();
 }
 
-TEST_F(LocalDeskDataManagerTest, AppendsDuplicateMarkingsCorrectly) {
-  data_manager_->AddOrUpdateEntry(
-      std::move(duplicate_pattern_matching_named_desk_),
-      base::BindOnce(&VerifyEntryAddedCorrectly));
-  data_manager_->AddOrUpdateEntry(
-      std::move(duplicate_pattern_matching_named_desk_two_),
-      base::BindOnce(&VerifyEntryAddedCorrectly));
-  data_manager_->AddOrUpdateEntry(
-      std::move(duplicate_pattern_matching_named_desk_three_),
-      base::BindOnce(&VerifyEntryAddedCorrectly));
-  base::RunLoop loop;
-  data_manager_->GetAllEntries(base::BindLambdaForTesting(
-      [&](DeskModel::GetAllEntriesStatus status,
-          const std::vector<const ash::DeskTemplate*>& entries) {
-        EXPECT_EQ(status, DeskModel::GetAllEntriesStatus::kOk);
-        EXPECT_EQ(entries.size(), 3ul);
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid7, entries));
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid8, entries));
-        EXPECT_TRUE(FindUuidInUuidList(kTestUuid9, entries));
+TEST_F(LocalDeskDataManagerTest, CanDetectNoDuplicateEntryNames) {
+  data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
+                                  base::BindOnce(&VerifyEntryAddedCorrectly));
+  data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
+                                  base::BindOnce(&VerifyEntryAddedCorrectly));
 
-        const ash::DeskTemplate* duplicate_one =
-            FindEntryInEntryList(kTestUuid8, entries);
-        EXPECT_NE(duplicate_one, nullptr);
-        EXPECT_EQ(
-            base::UTF16ToUTF8(duplicate_one->template_name()),
-            std::string(kDuplicatePatternMatchingNamedDeskExpectedNameOne));
-
-        const ash::DeskTemplate* duplicate_two =
-            FindEntryInEntryList(kTestUuid9, entries);
-        EXPECT_NE(duplicate_two, nullptr);
-        EXPECT_EQ(
-            base::UTF16ToUTF8(duplicate_two->template_name()),
-            std::string(kDuplicatePatternMatchingNamedDeskExpectedNameTwo));
-        loop.Quit();
-      }));
-  loop.Run();
+  EXPECT_FALSE(data_manager_->FindOtherEntryWithName(
+      base::UTF8ToUTF16(std::string("desk_01")),
+      ash::DeskTemplateType::kTemplate,
+      base::GUID::ParseCaseInsensitive(kTestUuid1)));
+  task_environment_.RunUntilIdle();
 }
 
 TEST_F(LocalDeskDataManagerTest, CanGetEntryByUuid) {
diff --git a/components/device_signals/core/common/BUILD.gn b/components/device_signals/core/common/BUILD.gn
index 3d707b7..42e98836 100644
--- a/components/device_signals/core/common/BUILD.gn
+++ b/components/device_signals/core/common/BUILD.gn
@@ -3,9 +3,14 @@
 # found in the LICENSE file.
 
 static_library("common") {
-  public = [ "signals_constants.h" ]
+  public = [
+    "signals_constants.h",
+    "system_signals_service_host.h",
+  ]
 
   sources = [ "signals_constants.cc" ]
+
+  public_deps = [ "//components/device_signals/core/common/mojom" ]
 }
 
 source_set("unit_tests") {
diff --git a/components/device_signals/core/common/mojom/BUILD.gn b/components/device_signals/core/common/mojom/BUILD.gn
index 763aef5..2d9e2cda 100644
--- a/components/device_signals/core/common/mojom/BUILD.gn
+++ b/components/device_signals/core/common/mojom/BUILD.gn
@@ -11,4 +11,31 @@
     "//mojo/public/mojom/base",
     "//sandbox/policy/mojom",
   ]
+
+  if (is_win) {
+    cpp_typemaps = [
+      {
+        types = [
+          {
+            mojom = "device_signals.mojom.AntiVirusProductState"
+            cpp = "::device_signals::AvProductState"
+          },
+          {
+            mojom = "device_signals.mojom.AntiVirusSignal"
+            cpp = "::device_signals::AvProduct"
+          },
+          {
+            mojom = "device_signals.mojom.HotfixSignal"
+            cpp = "::device_signals::InstalledHotfix"
+          },
+        ]
+        traits_headers = [ "system_signals_mojom_traits.h" ]
+        traits_sources = [ "system_signals_mojom_traits.cc" ]
+        traits_public_deps = [
+          "//base",
+          "//components/device_signals/core/common/win",
+        ]
+      },
+    ]
+  }
 }
diff --git a/components/device_signals/core/common/mojom/OWNERS b/components/device_signals/core/common/mojom/OWNERS
index 61b5e28..f486cf5 100644
--- a/components/device_signals/core/common/mojom/OWNERS
+++ b/components/device_signals/core/common/mojom/OWNERS
@@ -1,2 +1,5 @@
 per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
\ No newline at end of file
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/device_signals/core/common/mojom/system_signals.mojom b/components/device_signals/core/common/mojom/system_signals.mojom
index 6bdccd9..f335e66 100644
--- a/components/device_signals/core/common/mojom/system_signals.mojom
+++ b/components/device_signals/core/common/mojom/system_signals.mojom
@@ -40,12 +40,16 @@
   kOff,
   // The security product software is in the snoozed state, temporarily off,
   // and not actively protecting the computer.
-  kSnoozed
+  kSnoozed,
+  // The security product software is expired and does not have the latest
+  // updates.
+  kExpired
 };
 
 [EnableIf=is_win]
 struct AntiVirusSignal {
   string display_name;
+  string product_id;
   AntiVirusProductState state;
 };
 
@@ -57,6 +61,7 @@
 // Service in charge of collecting a specific set of device signals. The source
 // of these signals is platform-specific and, in some cases (i.e. Windows), may
 // need to be run a separate process.
+// This service can be accessed from the browser process.
 [ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox]
 interface SystemSignalsService {
   // Collects signals about a set of binary files specified by `requests`.
diff --git a/components/device_signals/core/common/mojom/system_signals_mojom_traits.cc b/components/device_signals/core/common/mojom/system_signals_mojom_traits.cc
new file mode 100644
index 0000000..22daec5
--- /dev/null
+++ b/components/device_signals/core/common/mojom/system_signals_mojom_traits.cc
@@ -0,0 +1,95 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/device_signals/core/common/mojom/system_signals_mojom_traits.h"
+
+#include "base/notreached.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace mojo {
+
+// static
+device_signals::mojom::AntiVirusProductState EnumTraits<
+    device_signals::mojom::AntiVirusProductState,
+    device_signals::AvProductState>::ToMojom(device_signals::AvProductState
+                                                 input) {
+  switch (input) {
+    case device_signals::AvProductState::kOn:
+      return device_signals::mojom::AntiVirusProductState::kOn;
+    case device_signals::AvProductState::kOff:
+      return device_signals::mojom::AntiVirusProductState::kOff;
+    case device_signals::AvProductState::kSnoozed:
+      return device_signals::mojom::AntiVirusProductState::kSnoozed;
+    case device_signals::AvProductState::kExpired:
+      return device_signals::mojom::AntiVirusProductState::kExpired;
+  }
+}
+
+// static
+bool EnumTraits<device_signals::mojom::AntiVirusProductState,
+                device_signals::AvProductState>::
+    FromMojom(device_signals::mojom::AntiVirusProductState input,
+              device_signals::AvProductState* output) {
+  absl::optional<device_signals::AvProductState> parsed_state;
+  switch (input) {
+    case device_signals::mojom::AntiVirusProductState::kOn:
+      parsed_state = device_signals::AvProductState::kOn;
+      break;
+    case device_signals::mojom::AntiVirusProductState::kOff:
+      parsed_state = device_signals::AvProductState::kOff;
+      break;
+    case device_signals::mojom::AntiVirusProductState::kSnoozed:
+      parsed_state = device_signals::AvProductState::kSnoozed;
+      break;
+    case device_signals::mojom::AntiVirusProductState::kExpired:
+      parsed_state = device_signals::AvProductState::kExpired;
+      break;
+  }
+
+  if (parsed_state.has_value()) {
+    *output = parsed_state.value();
+    return true;
+  }
+  return false;
+}
+
+// static
+bool StructTraits<device_signals::mojom::AntiVirusSignalDataView,
+                  device_signals::AvProduct>::
+    Read(device_signals::mojom::AntiVirusSignalDataView data,
+         device_signals::AvProduct* output) {
+  std::string display_name;
+  if (!data.ReadDisplayName(&display_name)) {
+    return false;
+  }
+  output->display_name = display_name;
+
+  std::string product_id;
+  if (!data.ReadProductId(&product_id)) {
+    return false;
+  }
+  output->product_id = product_id;
+
+  device_signals::AvProductState state;
+  if (!data.ReadState(&state)) {
+    return false;
+  }
+  output->state = state;
+  return true;
+}
+
+// static
+bool StructTraits<device_signals::mojom::HotfixSignalDataView,
+                  device_signals::InstalledHotfix>::
+    Read(device_signals::mojom::HotfixSignalDataView data,
+         device_signals::InstalledHotfix* output) {
+  std::string hotfix_id;
+  if (!data.ReadHotfixId(&hotfix_id)) {
+    return false;
+  }
+  output->hotfix_id = hotfix_id;
+  return true;
+}
+
+}  // namespace mojo
diff --git a/components/device_signals/core/common/mojom/system_signals_mojom_traits.h b/components/device_signals/core/common/mojom/system_signals_mojom_traits.h
new file mode 100644
index 0000000..7b1f546
--- /dev/null
+++ b/components/device_signals/core/common/mojom/system_signals_mojom_traits.h
@@ -0,0 +1,59 @@
+// 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 COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_MOJOM_SYSTEM_SIGNALS_MOJOM_TRAITS_H_
+#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_MOJOM_SYSTEM_SIGNALS_MOJOM_TRAITS_H_
+
+#include <string>
+
+#include "components/device_signals/core/common/mojom/system_signals.mojom-shared.h"
+#include "components/device_signals/core/common/win/win_types.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<device_signals::mojom::AntiVirusProductState,
+                  device_signals::AvProductState> {
+  static device_signals::mojom::AntiVirusProductState ToMojom(
+      device_signals::AvProductState input);
+  static bool FromMojom(device_signals::mojom::AntiVirusProductState input,
+                        device_signals::AvProductState* output);
+};
+
+template <>
+struct StructTraits<device_signals::mojom::AntiVirusSignalDataView,
+                    device_signals::AvProduct> {
+  static const std::string& display_name(
+      const device_signals::AvProduct& input) {
+    return input.display_name;
+  }
+
+  static const std::string& product_id(const device_signals::AvProduct& input) {
+    return input.product_id;
+  }
+
+  static device_signals::AvProductState state(
+      const device_signals::AvProduct& input) {
+    return input.state;
+  }
+
+  static bool Read(device_signals::mojom::AntiVirusSignalDataView data,
+                   device_signals::AvProduct* output);
+};
+
+template <>
+struct StructTraits<device_signals::mojom::HotfixSignalDataView,
+                    device_signals::InstalledHotfix> {
+  static const std::string& hotfix_id(
+      const device_signals::InstalledHotfix& input) {
+    return input.hotfix_id;
+  }
+
+  static bool Read(device_signals::mojom::HotfixSignalDataView input,
+                   device_signals::InstalledHotfix* output);
+};
+
+}  // namespace mojo
+
+#endif  // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_MOJOM_SYSTEM_SIGNALS_MOJOM_TRAITS_H_
\ No newline at end of file
diff --git a/components/device_signals/core/common/system_signals_service_host.h b/components/device_signals/core/common/system_signals_service_host.h
new file mode 100644
index 0000000..baab7232
--- /dev/null
+++ b/components/device_signals/core/common/system_signals_service_host.h
@@ -0,0 +1,25 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_SYSTEM_SIGNALS_SERVICE_HOST_H_
+#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_SYSTEM_SIGNALS_SERVICE_HOST_H_
+
+#include "components/device_signals/core/common/mojom/system_signals.mojom-shared.h"
+
+namespace device_signals {
+
+// Class in charge of creating and handling the service's lifecycle. Clients of
+// SystemSignalsService should always go through a common instance of this class
+// to retrieve a service instance.
+class SystemSignalsServiceHost {
+ public:
+  virtual ~SystemSignalsServiceHost() = default;
+
+  // Returns a pointer to the currently available SystemSignalsService instance.
+  virtual device_signals::mojom::SystemSignalsService* GetService() = 0;
+};
+
+}  // namespace device_signals
+
+#endif  // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_SYSTEM_SIGNALS_SERVICE_HOST_H_
diff --git a/components/device_signals/core/common/win/BUILD.gn b/components/device_signals/core/common/win/BUILD.gn
index 89ed223..41116ac 100644
--- a/components/device_signals/core/common/win/BUILD.gn
+++ b/components/device_signals/core/common/win/BUILD.gn
@@ -29,10 +29,16 @@
   sources = [
     "com_fakes.cc",
     "com_fakes.h",
+    "mock_wmi_client.cc",
+    "mock_wmi_client.h",
+    "mock_wsc_client.cc",
+    "mock_wsc_client.h",
   ]
 
   deps = [
+    ":win",
     "//base",
+    "//testing/gmock",
     "//testing/gtest",
     "//third_party/abseil-cpp:absl",
   ]
diff --git a/components/device_signals/core/common/win/mock_wmi_client.cc b/components/device_signals/core/common/win/mock_wmi_client.cc
new file mode 100644
index 0000000..f12f35b
--- /dev/null
+++ b/components/device_signals/core/common/win/mock_wmi_client.cc
@@ -0,0 +1,12 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/device_signals/core/common/win/mock_wmi_client.h"
+
+namespace device_signals {
+
+MockWmiClient::MockWmiClient() = default;
+MockWmiClient::~MockWmiClient() = default;
+
+}  // namespace device_signals
diff --git a/components/device_signals/core/common/win/mock_wmi_client.h b/components/device_signals/core/common/win/mock_wmi_client.h
new file mode 100644
index 0000000..ac934b7
--- /dev/null
+++ b/components/device_signals/core/common/win/mock_wmi_client.h
@@ -0,0 +1,23 @@
+// Copyright (c) 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 COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WMI_CLIENT_H_
+#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WMI_CLIENT_H_
+
+#include "components/device_signals/core/common/win/wmi_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace device_signals {
+
+class MockWmiClient : public WmiClient {
+ public:
+  MockWmiClient();
+  ~MockWmiClient() override;
+
+  MOCK_METHOD(WmiHotfixesResponse, GetInstalledHotfixes, (), (override));
+};
+
+}  // namespace device_signals
+
+#endif  // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WMI_CLIENT_H_
diff --git a/components/device_signals/core/common/win/mock_wsc_client.cc b/components/device_signals/core/common/win/mock_wsc_client.cc
new file mode 100644
index 0000000..18bb169
--- /dev/null
+++ b/components/device_signals/core/common/win/mock_wsc_client.cc
@@ -0,0 +1,12 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/device_signals/core/common/win/mock_wsc_client.h"
+
+namespace device_signals {
+
+MockWscClient::MockWscClient() = default;
+MockWscClient::~MockWscClient() = default;
+
+}  // namespace device_signals
diff --git a/components/device_signals/core/common/win/mock_wsc_client.h b/components/device_signals/core/common/win/mock_wsc_client.h
new file mode 100644
index 0000000..080dfa5
--- /dev/null
+++ b/components/device_signals/core/common/win/mock_wsc_client.h
@@ -0,0 +1,23 @@
+// Copyright (c) 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 COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WSC_CLIENT_H_
+#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WSC_CLIENT_H_
+
+#include "components/device_signals/core/common/win/wsc_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace device_signals {
+
+class MockWscClient : public WscClient {
+ public:
+  MockWscClient();
+  ~MockWscClient() override;
+
+  MOCK_METHOD(WscAvProductsResponse, GetAntiVirusProducts, (), (override));
+};
+
+}  // namespace device_signals
+
+#endif  // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_MOCK_WMI_CLIENT_H_
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc
index 3816bf7..b96612a1 100644
--- a/components/feed/core/v2/metrics_reporter.cc
+++ b/components/feed/core/v2/metrics_reporter.cc
@@ -587,6 +587,9 @@
     case FeedUserActionType::kShowUnfollowFailedSnackbar:
     case FeedUserActionType::kTappedGoToFeedOnSnackbar:
     case FeedUserActionType::kTappedCrowButton:
+    case FeedUserActionType::kFirstFollowSheetShown:
+    case FeedUserActionType::kFirstFollowSheetTappedGoToFeed:
+    case FeedUserActionType::kFirstFollowSheetTappedGotIt:
       // Nothing additional for these actions. Note that some of these are iOS
       // only.
 
diff --git a/components/feed/core/v2/public/common_enums.cc b/components/feed/core/v2/public/common_enums.cc
index 005992c..f219376 100644
--- a/components/feed/core/v2/public/common_enums.cc
+++ b/components/feed/core/v2/public/common_enums.cc
@@ -118,6 +118,12 @@
       return out << "kTappedGoToFeedOnSnackbar";
     case FeedUserActionType::kTappedCrowButton:
       return out << "kTappedCrow";
+    case FeedUserActionType::kFirstFollowSheetShown:
+      return out << "kFirstFollowSheetShown";
+    case FeedUserActionType::kFirstFollowSheetTappedGoToFeed:
+      return out << "kFirstFollowSheetTappedGoToFeed";
+    case FeedUserActionType::kFirstFollowSheetTappedGotIt:
+      return out << "kFirstFollowSheetTappedGotIt";
   }
 }
 
diff --git a/components/feed/core/v2/public/common_enums.h b/components/feed/core/v2/public/common_enums.h
index 8b26c84..dfe5bd0 100644
--- a/components/feed/core/v2/public/common_enums.h
+++ b/components/feed/core/v2/public/common_enums.h
@@ -148,8 +148,15 @@
   kTappedGoToFeedOnSnackbar = 52,
   // User tapped the Crow button in the context menu.
   kTappedCrowButton = 53,
+  // User action caused a first follow sheet to be shown. User action not
+  // reported here. iOS only.
+  kFirstFollowSheetShown = 54,
+  // User tapped the "Go To Feed" button on the first follow sheet. (IOS)
+  kFirstFollowSheetTappedGoToFeed = 55,
+  // User tapped the "Got It" button on the first follow sheet. (IOS)
+  kFirstFollowSheetTappedGotIt = 56,
 
-  kMaxValue = kTappedCrowButton,
+  kMaxValue = kFirstFollowSheetTappedGotIt,
 };
 
 // For testing and debugging only.
diff --git a/components/heap_profiling/in_process/heap_profiler_controller.cc b/components/heap_profiling/in_process/heap_profiler_controller.cc
index 77e26ad..61523cc3 100644
--- a/components/heap_profiling/in_process/heap_profiler_controller.cc
+++ b/components/heap_profiling/in_process/heap_profiler_controller.cc
@@ -6,6 +6,7 @@
 
 #include <cmath>
 #include <limits>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/feature_list.h"
@@ -140,6 +141,23 @@
 constexpr base::Feature HeapProfilerController::kHeapProfilerReporting{
     "HeapProfilerReporting", base::FEATURE_ENABLED_BY_DEFAULT};
 
+HeapProfilerController::SnapshotParams::SnapshotParams(
+    base::TimeDelta mean_interval,
+    bool use_random_interval,
+    scoped_refptr<StoppedFlag> stopped)
+    : mean_interval(mean_interval),
+      use_random_interval(use_random_interval),
+      stopped(std::move(stopped)) {}
+
+HeapProfilerController::SnapshotParams::~SnapshotParams() = default;
+
+HeapProfilerController::SnapshotParams::SnapshotParams(SnapshotParams&& other) =
+    default;
+
+HeapProfilerController::SnapshotParams&
+HeapProfilerController::SnapshotParams::operator=(SnapshotParams&& other) =
+    default;
+
 HeapProfilerController::HeapProfilerController(version_info::Channel channel)
     : profiling_enabled_(DecideIfCollectionIsEnabled(channel)),
       stopped_(base::MakeRefCounted<StoppedFlag>()) {}
@@ -159,9 +177,10 @@
   base::SamplingHeapProfiler::Get()->Start();
   const int interval = kCollectionIntervalMinutes.Get();
   DCHECK_GT(interval, 0);
-  ScheduleNextSnapshot(
-      stopped_, {.interval = base::Minutes(interval),
-                 .use_random_interval = !suppress_randomness_for_testing_});
+  SnapshotParams params(
+      /*mean_interval=*/base::Minutes(interval),
+      /*use_random_interval=*/!suppress_randomness_for_testing_, stopped_);
+  ScheduleNextSnapshot(std::move(params));
 }
 
 void HeapProfilerController::SuppressRandomnessForTesting() {
@@ -169,31 +188,26 @@
 }
 
 // static
-void HeapProfilerController::ScheduleNextSnapshot(
-    scoped_refptr<StoppedFlag> stopped,
-    CollectionInterval heap_collection_interval) {
-  base::TimeDelta interval =
-      heap_collection_interval.use_random_interval
-          ? RandomInterval(heap_collection_interval.interval)
-          : heap_collection_interval.interval;
+void HeapProfilerController::ScheduleNextSnapshot(SnapshotParams params) {
+  base::TimeDelta interval = params.use_random_interval
+                                 ? RandomInterval(params.mean_interval)
+                                 : params.mean_interval;
   RecordUmaSnapshotInterval(interval, "Scheduled");
   base::ThreadPool::PostDelayedTask(
       FROM_HERE, {base::TaskPriority::BEST_EFFORT},
-      base::BindOnce(&HeapProfilerController::TakeSnapshot, std::move(stopped),
-                     heap_collection_interval, /*previous_interval=*/interval),
+      base::BindOnce(&HeapProfilerController::TakeSnapshot, std::move(params),
+                     /*previous_interval=*/interval),
       interval);
 }
 
 // static
-void HeapProfilerController::TakeSnapshot(
-    scoped_refptr<StoppedFlag> stopped,
-    CollectionInterval heap_collection_interval,
-    base::TimeDelta previous_interval) {
-  if (stopped->data.IsSet())
+void HeapProfilerController::TakeSnapshot(SnapshotParams params,
+                                          base::TimeDelta previous_interval) {
+  if (params.stopped->data.IsSet())
     return;
   RecordUmaSnapshotInterval(previous_interval, "Taken");
   RetrieveAndSendSnapshot();
-  ScheduleNextSnapshot(std::move(stopped), heap_collection_interval);
+  ScheduleNextSnapshot(std::move(params));
 }
 
 // static
diff --git a/components/heap_profiling/in_process/heap_profiler_controller.h b/components/heap_profiling/in_process/heap_profiler_controller.h
index 65ce892..241dc94 100644
--- a/components/heap_profiling/in_process/heap_profiler_controller.h
+++ b/components/heap_profiling/in_process/heap_profiler_controller.h
@@ -70,19 +70,38 @@
  private:
   using StoppedFlag = base::RefCountedData<base::AtomicFlag>;
 
-  struct CollectionInterval {
-    base::TimeDelta interval;
-    bool use_random_interval = false;
-  };
-  static void ScheduleNextSnapshot(scoped_refptr<StoppedFlag> stopped,
-                                   CollectionInterval heap_collection_interval);
+  // Parameters to control the snapshot sampling and reporting. This is
+  // move-only so that it can be safely passed between threads to the static
+  // snapshot functions.
+  struct SnapshotParams {
+    SnapshotParams(base::TimeDelta mean_interval,
+                   bool use_random_interval,
+                   scoped_refptr<StoppedFlag> stopped);
+    ~SnapshotParams();
 
-  // Takes a heap snapshot unless the `stopped` flag is set.
-  // `heap_collection_interval` is used to schedule the next snapshot.
+    // Move-only.
+    SnapshotParams(const SnapshotParams& other) = delete;
+    SnapshotParams& operator=(const SnapshotParams& other) = delete;
+    SnapshotParams(SnapshotParams&& other);
+    SnapshotParams& operator=(SnapshotParams&& other);
+
+    // Mean interval until the next snapshot.
+    base::TimeDelta mean_interval;
+
+    // If true, generate a random time centered around `mean_interval`.
+    // Otherwise use `mean_interval` exactly.
+    bool use_random_interval = false;
+
+    // Atomic flag to signal that no more snapshots should be taken.
+    scoped_refptr<StoppedFlag> stopped;
+  };
+
+  static void ScheduleNextSnapshot(SnapshotParams params);
+
+  // Takes a heap snapshot unless the `params.stopped` flag is set.
   // `previous_interval` is the time since the previous snapshot, which is used
   // to log metrics about snapshot frequency.
-  static void TakeSnapshot(scoped_refptr<StoppedFlag> stopped,
-                           CollectionInterval heap_collection_interval,
+  static void TakeSnapshot(SnapshotParams params,
                            base::TimeDelta previous_interval);
 
   static void RetrieveAndSendSnapshot();
@@ -91,6 +110,10 @@
   // and the probability parameters of the HeapProfilerReporting feature.
   const bool profiling_enabled_;
 
+  // This flag is set when the HeapProfilerController is torn down, to stop
+  // profiling. It is the only member that should be referenced by the static
+  // functions, to be sure that they can run on the thread pool while
+  // HeapProfilerController is deleted on the main thread.
   scoped_refptr<StoppedFlag> stopped_;
   bool suppress_randomness_for_testing_ = false;
 };
diff --git a/components/navigation_metrics/navigation_metrics.cc b/components/navigation_metrics/navigation_metrics.cc
index 3d44987e..88095ae 100644
--- a/components/navigation_metrics/navigation_metrics.cc
+++ b/components/navigation_metrics/navigation_metrics.cc
@@ -68,8 +68,7 @@
     bool is_off_the_record,
     profile_metrics::BrowserProfileType profile_type) {
   Scheme scheme = GetScheme(url);
-  UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameScheme2", scheme,
-                            Scheme::COUNT);
+  UMA_HISTOGRAM_ENUMERATION(kMainFrameScheme, scheme, Scheme::COUNT);
   if (!is_same_document) {
     UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameSchemeDifferentPage2",
                               scheme, Scheme::COUNT);
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 05a0fb35..2f0a46f 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -118,7 +118,8 @@
     DCHECK(kMaxAutocompletePositionValue > field_trial_value);
 #if BUILDFLAG(IS_IOS)
     if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) {
-      field_trial_value = MIN(field_trial_value, kMaxZeroSuggestMatchesOnIPad);
+      field_trial_value =
+          std::min(field_trial_value, kMaxZeroSuggestMatchesOnIPad);
     }
 #endif
     return field_trial_value;
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index d7a0b6dd..73d981b1 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -488,9 +488,9 @@
 int OmniboxFieldTrial::MaxNumHQPUrlsIndexedAtStartup() {
 #if BUILDFLAG(IS_ANDROID)
   // Limits on Android are chosen based on experiment results. See
-  // crbug.com/715852#c18.
+  // crbug.com/715852#c18 and crbug.com/1141539#c31.
   constexpr int kDefaultOnLowEndDevices = 100;
-  constexpr int kDefaultOnNonLowEndDevices = 1000;
+  constexpr int kDefaultOnNonLowEndDevices = 400;
 #else
   // Use 20,000 entries as a safety cap for users with spammed history,
   // such as users who were stuck in a redirect loop with autogenerated URLs.
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index 030dc86f..10f7a92 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -181,7 +181,7 @@
 // over 10% of all shutdown hangs.
 const base::Feature kHistoryQuickProviderAblateInMemoryURLIndexCacheFile{
     "OmniboxHistoryQuickProviderAblateInMemoryURLIndexCacheFile",
-    enabled_by_default_desktop_only};
+    enabled_by_default_desktop_android};
 
 // If enabled, suggestions from a cgi param name match are scored to 0.
 const base::Feature kDisableCGIParamMatching{"OmniboxDisableCGIParamMatching",
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn
index ec0a664..1f590635 100644
--- a/components/policy/core/common/BUILD.gn
+++ b/components/policy/core/common/BUILD.gn
@@ -333,8 +333,8 @@
       sources += [
         "policy_loader_mac.h",
         "policy_loader_mac.mm",
-        "preferences_mac.cc",
         "preferences_mac.h",
+        "preferences_mac.mm",
       ]
       frameworks += [ "SystemConfiguration.framework" ]
     }
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc
index 06ac357..954caa6d 100644
--- a/components/policy/core/common/features.cc
+++ b/components/policy/core/common/features.cc
@@ -32,6 +32,10 @@
 
 const base::Feature kDmTokenDeletion{"DmTokenDeletion",
                                      base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kPolicyScopeDetectionMac{"PolicyScopeDetectionMac",
+                                             base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace features
 
 }  // namespace policy
diff --git a/components/policy/core/common/features.h b/components/policy/core/common/features.h
index 2777e81..e36c04c8 100644
--- a/components/policy/core/common/features.h
+++ b/components/policy/core/common/features.h
@@ -42,6 +42,10 @@
 // deleted from CBCM.
 POLICY_EXPORT extern const base::Feature kDmTokenDeletion;
 
+// Allow mac to detect policy scope with a private API. The feature is limited
+// in the policy component only.
+extern const base::Feature kPolicyScopeDetectionMac;
+
 }  // namespace features
 }  // namespace policy
 
diff --git a/components/policy/core/common/policy_loader_mac.mm b/components/policy/core/common/policy_loader_mac.mm
index 03583403..13540d0 100644
--- a/components/policy/core/common/policy_loader_mac.mm
+++ b/components/policy/core/common/policy_loader_mac.mm
@@ -6,11 +6,12 @@
 
 #include <utility>
 
+#include <Foundation/Foundation.h>
+
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/enterprise_util.h"
-#include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/mac/foundation_util.h"
@@ -20,7 +21,6 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "components/policy/core/common/external_data_fetcher.h"
-#include "components/policy/core/common/features.h"
 #include "components/policy/core/common/mac_util.h"
 #include "components/policy/core/common/policy_bundle.h"
 #include "components/policy/core/common/policy_load_status.h"
@@ -128,11 +128,16 @@
     bool forced = preferences_->AppValueIsForced(name, application_id_);
     PolicyLevel level =
         forced ? POLICY_LEVEL_MANDATORY : POLICY_LEVEL_RECOMMENDED;
-    // TODO(joaodasilva): figure the policy scope.
+    PolicyScope scope = POLICY_SCOPE_USER;
+    if (forced) {
+      scope = preferences_->IsManagedPolicyAvailableForMachineScope(name)
+                  ? POLICY_SCOPE_MACHINE
+                  : POLICY_SCOPE_USER;
+    }
     std::unique_ptr<base::Value> policy = PropertyToValue(value);
     if (policy) {
-      chrome_policy.Set(it.key(), level, POLICY_SCOPE_MACHINE,
-                        POLICY_SOURCE_PLATFORM, std::move(*policy), nullptr);
+      chrome_policy.Set(it.key(), level, scope, POLICY_SOURCE_PLATFORM,
+                        std::move(*policy), nullptr);
     } else {
       status.Add(POLICY_LOAD_STATUS_PARSE_ERROR);
     }
@@ -226,9 +231,15 @@
     bool forced = preferences_->AppValueIsForced(pref_name, bundle_id);
     PolicyLevel level =
         forced ? POLICY_LEVEL_MANDATORY : POLICY_LEVEL_RECOMMENDED;
+    PolicyScope scope = POLICY_SCOPE_USER;
+    if (forced) {
+      scope = preferences_->IsManagedPolicyAvailableForMachineScope(pref_name)
+                  ? POLICY_SCOPE_MACHINE
+                  : POLICY_SCOPE_USER;
+    }
     std::unique_ptr<base::Value> policy_value = PropertyToValue(value);
     if (policy_value) {
-      policy->Set(it.key(), level, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
+      policy->Set(it.key(), level, scope, POLICY_SOURCE_PLATFORM,
                   std::move(*policy_value), nullptr);
     }
   }
diff --git a/components/policy/core/common/policy_loader_mac_unittest.cc b/components/policy/core/common/policy_loader_mac_unittest.cc
index c8f0ca8..ed39ba0 100644
--- a/components/policy/core/common/policy_loader_mac_unittest.cc
+++ b/components/policy/core/common/policy_loader_mac_unittest.cc
@@ -87,7 +87,7 @@
                                       const std::string& policy_value) {
   ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
   ScopedCFTypeRef<CFStringRef> value(base::SysUTF8ToCFStringRef(policy_value));
-  prefs_->AddTestItem(name, value, true);
+  prefs_->AddTestItem(name, value, /*is_forced=*/true, /*is_machine=*/true);
 }
 
 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
@@ -95,15 +95,14 @@
   ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
   ScopedCFTypeRef<CFNumberRef> value(
       CFNumberCreate(NULL, kCFNumberIntType, &policy_value));
-  prefs_->AddTestItem(name, value, true);
+  prefs_->AddTestItem(name, value, /*is_forced=*/true, /*is_machine=*/true);
 }
 
 void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
                                        bool policy_value) {
   ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
-  prefs_->AddTestItem(name,
-                      policy_value ? kCFBooleanTrue : kCFBooleanFalse,
-                      true);
+  prefs_->AddTestItem(name, policy_value ? kCFBooleanTrue : kCFBooleanFalse,
+                      /*is_forced=*/true, /*is_machine=*/true);
 }
 
 void TestHarness::InstallStringListPolicy(const std::string& policy_name,
@@ -111,7 +110,7 @@
   ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
   ScopedCFTypeRef<CFPropertyListRef> array(ValueToProperty(*policy_value));
   ASSERT_TRUE(array);
-  prefs_->AddTestItem(name, array, true);
+  prefs_->AddTestItem(name, array, /*is_forced=*/true, /*is_machine=*/true);
 }
 
 void TestHarness::InstallDictionaryPolicy(const std::string& policy_name,
@@ -119,7 +118,7 @@
   ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
   ScopedCFTypeRef<CFPropertyListRef> dict(ValueToProperty(*policy_value));
   ASSERT_TRUE(dict);
-  prefs_->AddTestItem(name, dict, true);
+  prefs_->AddTestItem(name, dict, /*is_forced=*/true, /*is_machine=*/true);
 }
 
 // static
@@ -169,8 +168,10 @@
       CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(buffer),
                    std::size(buffer)));
   ASSERT_TRUE(invalid_data);
-  prefs_->AddTestItem(name, invalid_data.get(), true);
-  prefs_->AddTestItem(name, invalid_data.get(), false);
+  prefs_->AddTestItem(name, invalid_data.get(), /*is_forced=*/true,
+                      /*is_machine=*/true);
+  prefs_->AddTestItem(name, invalid_data.get(), /*is_forced=*/false,
+                      /*is_machine=*/true);
 
   // Make the provider read the updated |prefs_|.
   provider_->RefreshPolicies();
@@ -185,16 +186,35 @@
   ScopedCFTypeRef<CFPropertyListRef> test_value(
       base::SysUTF8ToCFStringRef("string value"));
   ASSERT_TRUE(test_value.get());
-  prefs_->AddTestItem(name, test_value.get(), false);
+  prefs_->AddTestItem(name, test_value.get(), /*is_forced=*/false,
+                      /*is_machine=*/true);
 
   // Make the provider read the updated |prefs_|.
   provider_->RefreshPolicies();
   task_environment_.RunUntilIdle();
   PolicyBundle expected_bundle;
   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
-      .Set(test_keys::kKeyString, POLICY_LEVEL_RECOMMENDED,
-           POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
-           base::Value("string value"), nullptr);
+      .Set(test_keys::kKeyString, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
+           POLICY_SOURCE_PLATFORM, base::Value("string value"), nullptr);
+  EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
+}
+
+TEST_F(PolicyLoaderMacTest, TestUserScopeValue) {
+  ScopedCFTypeRef<CFStringRef> name(
+      base::SysUTF8ToCFStringRef(test_keys::kKeyString));
+  ScopedCFTypeRef<CFPropertyListRef> test_value(
+      base::SysUTF8ToCFStringRef("string value"));
+  ASSERT_TRUE(test_value.get());
+  prefs_->AddTestItem(name, test_value.get(), /*is_forced=*/true,
+                      /*is_machine=*/false);
+
+  // Make the provider read the updated |prefs_|.
+  provider_->RefreshPolicies();
+  task_environment_.RunUntilIdle();
+  PolicyBundle expected_bundle;
+  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+      .Set(test_keys::kKeyString, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+           POLICY_SOURCE_PLATFORM, base::Value("string value"), nullptr);
   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
 }
 
diff --git a/components/policy/core/common/preferences_mac.cc b/components/policy/core/common/preferences_mac.cc
deleted file mode 100644
index e65b1623..0000000
--- a/components/policy/core/common/preferences_mac.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/policy/core/common/preferences_mac.h"
-
-Boolean MacPreferences::AppSynchronize(CFStringRef applicationID) {
-  return CFPreferencesAppSynchronize(applicationID);
-}
-
-CFPropertyListRef MacPreferences::CopyAppValue(CFStringRef key,
-                                               CFStringRef applicationID) {
-  return CFPreferencesCopyAppValue(key, applicationID);
-}
-
-Boolean MacPreferences::AppValueIsForced(CFStringRef key,
-                                         CFStringRef applicationID) {
-  return CFPreferencesAppValueIsForced(key, applicationID);
-}
diff --git a/components/policy/core/common/preferences_mac.h b/components/policy/core/common/preferences_mac.h
index baa7d7e..e897f9e 100644
--- a/components/policy/core/common/preferences_mac.h
+++ b/components/policy/core/common/preferences_mac.h
@@ -7,27 +7,50 @@
 
 #include <CoreFoundation/CoreFoundation.h>
 
+#include <memory>
+
 #include "components/policy/policy_export.h"
 
-// Wraps a small part of the CFPreferences API surface in a very thin layer, to
-// allow it to be mocked out for testing.
+// Wraps a small part of the `CFPreferences` and `CFPrefsManagedSource` API
+// surface.
 
-// See CFPreferences documentation for function documentation, as these call
-// through directly to their CFPreferences equivalents (Foo ->
-// CFPreferencesFoo).
+// See CFPreferences documentation for following functions' documentation:
+//  AppSynchronize()
+//  CopyAppValue()
+//  AppValueIsForced()
 class POLICY_EXPORT MacPreferences {
  public:
-  MacPreferences() {}
+  // Wraps Apple's private `CFPrefsManagedSource` API to determine the scope of
+  // a policy.
+  class PolicyScope {
+   public:
+    virtual ~PolicyScope() = default;
+    virtual void Init(CFStringRef application_id) = 0;
+    virtual Boolean IsManagedPolicyAvailable(CFStringRef key) = 0;
+  };
+
+  MacPreferences();
   MacPreferences(const MacPreferences&) = delete;
   MacPreferences& operator=(const MacPreferences&) = delete;
-  virtual ~MacPreferences() {}
+  virtual ~MacPreferences();
 
-  virtual Boolean AppSynchronize(CFStringRef applicationID);
+  // Calls CFPreferencesAppSynchronize and initialize `policy_scope_`.
+  virtual Boolean AppSynchronize(CFStringRef application_id);
 
+  // Calls CFPreferencesCopyAppValue.
   virtual CFPropertyListRef CopyAppValue(CFStringRef key,
-                                         CFStringRef applicationID);
+                                         CFStringRef application_id);
 
-  virtual Boolean AppValueIsForced(CFStringRef key, CFStringRef applicationID);
+  // Calls CFPreferencesAppValueIsForced.
+  virtual Boolean AppValueIsForced(CFStringRef key, CFStringRef application_id);
+
+  // Calls CFPrefsManagedSource.copyValueForKey to determine if the policy is
+  // set at the machine scope for `application_id` that is set by
+  // `AppSynchronize()` function above.
+  virtual Boolean IsManagedPolicyAvailableForMachineScope(CFStringRef key);
+
+ private:
+  std::unique_ptr<PolicyScope> policy_scope_;
 };
 
 #endif  // COMPONENTS_POLICY_CORE_COMMON_PREFERENCES_MAC_H_
diff --git a/components/policy/core/common/preferences_mac.mm b/components/policy/core/common/preferences_mac.mm
new file mode 100644
index 0000000..4f1967c
--- /dev/null
+++ b/components/policy/core/common/preferences_mac.mm
@@ -0,0 +1,118 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Foundation/Foundation.h>
+#import <objc/runtime.h>
+
+#include "base/feature_list.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsobject.h"
+#include "components/policy/core/common/features.h"
+#include "components/policy/core/common/preferences_mac.h"
+
+// `CFPrefsManagedSource` and `_CFXPreferences` are used to determine the scope
+// of a policy. A policy can be read with `copyValueForKey()` below with
+// `kCFPreferencesAnyUser` will be treated as machine scope policy. Otherwise,
+// it will be user scope policy. The implementation of these two interfaces are
+// only available during runtime and will be obtained with `objc_getClass()`.
+@interface _CFXPreferences : NSObject
+@end
+
+@interface CFPrefsManagedSource : NSObject
+- (instancetype)initWithDomain:(NSString*)domain
+                          user:(NSString*)user
+                        byHost:(BOOL)by_host
+                 containerPath:(NSString*)path
+         containingPreferences:(_CFXPreferences*)contain_prefs;
+- (id)copyValueForKey:(NSString*)key;
+@end
+
+namespace {
+
+base::scoped_nsobject<_CFXPreferences> CreateCFXPrefs() {
+  // _CFXPreferences is only available during runtime.
+  return base::scoped_nsobject<_CFXPreferences>(
+      [[objc_getClass("_CFXPreferences") alloc] init]);
+}
+
+base::scoped_nsobject<CFPrefsManagedSource>
+CreateCFPrefsManagedSourceForMachine(CFStringRef application_id, id cfxPrefs) {
+  if (!cfxPrefs)
+    return base::scoped_nsobject<CFPrefsManagedSource>();
+
+  // CFPrefsManagedSource is only available during runtime.
+  base::scoped_nsobject<CFPrefsManagedSource> source(
+      [objc_getClass("CFPrefsManagedSource") alloc]);
+
+  if (![source respondsToSelector:@selector
+               (initWithDomain:
+                          user:byHost:containerPath:containingPreferences:)] ||
+      ![source respondsToSelector:@selector(copyValueForKey:)]) {
+    return base::scoped_nsobject<CFPrefsManagedSource>();
+  }
+
+  [source initWithDomain:base::mac::CFToNSCast(application_id)
+                       user:base::mac::CFToNSCast(kCFPreferencesAnyUser)
+                     byHost:YES
+              containerPath:nil
+      containingPreferences:cfxPrefs];
+  return source;
+}
+
+class MachinePolicyScope : public MacPreferences::PolicyScope {
+ public:
+  MachinePolicyScope() = default;
+  ~MachinePolicyScope() override = default;
+
+  void Init(CFStringRef application_id) override {
+    if (!base::FeatureList::IsEnabled(
+            policy::features::kPolicyScopeDetectionMac)) {
+      return;
+    }
+    if (!cfx_prefs_)
+      cfx_prefs_.reset(CreateCFXPrefs());
+    machine_scope_.reset(
+        CreateCFPrefsManagedSourceForMachine(application_id, cfx_prefs_));
+  }
+
+  Boolean IsManagedPolicyAvailable(CFStringRef key) override {
+    if (!base::FeatureList::IsEnabled(
+            policy::features::kPolicyScopeDetectionMac)) {
+      return YES;
+    }
+    if (!machine_scope_)
+      return YES;
+    return [machine_scope_ copyValueForKey:base::mac::CFToNSCast(key)] != nil;
+  }
+
+ private:
+  base::scoped_nsobject<_CFXPreferences> cfx_prefs_;
+  base::scoped_nsobject<CFPrefsManagedSource> machine_scope_;
+};
+
+}  // namespace
+
+MacPreferences::MacPreferences()
+    : policy_scope_(std::make_unique<MachinePolicyScope>()) {}
+MacPreferences::~MacPreferences() = default;
+
+Boolean MacPreferences::AppSynchronize(CFStringRef application_id) {
+  policy_scope_->Init(application_id);
+  return CFPreferencesAppSynchronize(application_id);
+}
+
+CFPropertyListRef MacPreferences::CopyAppValue(CFStringRef key,
+                                               CFStringRef application_id) {
+  return CFPreferencesCopyAppValue(key, application_id);
+}
+
+Boolean MacPreferences::AppValueIsForced(CFStringRef key,
+                                         CFStringRef application_id) {
+  return CFPreferencesAppValueIsForced(key, application_id);
+}
+
+Boolean MacPreferences::IsManagedPolicyAvailableForMachineScope(
+    CFStringRef key) {
+  return policy_scope_->IsManagedPolicyAvailable(key);
+}
diff --git a/components/policy/core/common/preferences_mock_mac.cc b/components/policy/core/common/preferences_mock_mac.cc
index bc51c9a..76ec203 100644
--- a/components/policy/core/common/preferences_mock_mac.cc
+++ b/components/policy/core/common/preferences_mock_mac.cc
@@ -12,17 +12,19 @@
   forced_.reset(CFSetCreateMutable(kCFAllocatorDefault,
                                    0,
                                    &kCFTypeSetCallBacks));
+  machine_.reset(
+      CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks));
 }
 
 MockPreferences::~MockPreferences() {
 }
 
-Boolean MockPreferences::AppSynchronize(CFStringRef applicationID) {
+Boolean MockPreferences::AppSynchronize(CFStringRef application_id) {
   return true;
 }
 
 CFPropertyListRef MockPreferences::CopyAppValue(CFStringRef key,
-                                                CFStringRef applicationID) {
+                                                CFStringRef application_id) {
   CFPropertyListRef value;
   Boolean found = CFDictionaryGetValueIfPresent(values_,
                                                 key,
@@ -34,14 +36,22 @@
 }
 
 Boolean MockPreferences::AppValueIsForced(CFStringRef key,
-                                          CFStringRef applicationID) {
+                                          CFStringRef application_id) {
   return CFSetContainsValue(forced_, key);
 }
 
+Boolean MockPreferences::IsManagedPolicyAvailableForMachineScope(
+    CFStringRef key) {
+  return CFSetContainsValue(machine_, key);
+}
+
 void MockPreferences::AddTestItem(CFStringRef key,
                                   CFPropertyListRef value,
-                                  bool is_forced) {
+                                  bool is_forced,
+                                  bool is_machine) {
   CFDictionarySetValue(values_, key, value);
   if (is_forced)
     CFSetAddValue(forced_, key);
+  if (is_machine)
+    CFSetAddValue(machine_, key);
 }
diff --git a/components/policy/core/common/preferences_mock_mac.h b/components/policy/core/common/preferences_mock_mac.h
index 8f3df0c8..4ebd9fc 100644
--- a/components/policy/core/common/preferences_mock_mac.h
+++ b/components/policy/core/common/preferences_mock_mac.h
@@ -15,19 +15,24 @@
   MockPreferences();
   ~MockPreferences() override;
 
-  Boolean AppSynchronize(CFStringRef applicationID) override;
-
+  // MacPreferences
+  Boolean AppSynchronize(CFStringRef application_id) override;
   CFPropertyListRef CopyAppValue(CFStringRef key,
-                                 CFStringRef applicationID) override;
-
-  Boolean AppValueIsForced(CFStringRef key, CFStringRef applicationID) override;
+                                 CFStringRef application_id) override;
+  Boolean AppValueIsForced(CFStringRef key,
+                           CFStringRef application_id) override;
+  Boolean IsManagedPolicyAvailableForMachineScope(CFStringRef key) override;
 
   // Adds a preference item with the given info to the test set.
-  void AddTestItem(CFStringRef key, CFPropertyListRef value, bool is_forced);
+  void AddTestItem(CFStringRef key,
+                   CFPropertyListRef value,
+                   bool is_forced,
+                   bool is_machine);
 
  private:
   base::ScopedCFTypeRef<CFMutableDictionaryRef> values_;
   base::ScopedCFTypeRef<CFMutableSetRef> forced_;
+  base::ScopedCFTypeRef<CFMutableSetRef> machine_;
 };
 
 #endif  // COMPONENTS_POLICY_CORE_COMMON_PREFERENCES_MOCK_MAC_H_
diff --git a/components/segmentation_platform/internal/execution/optimization_guide/optimization_guide_segmentation_model_provider.cc b/components/segmentation_platform/internal/execution/optimization_guide/optimization_guide_segmentation_model_provider.cc
index 512614b..0658c30c 100644
--- a/components/segmentation_platform/internal/execution/optimization_guide/optimization_guide_segmentation_model_provider.cc
+++ b/components/segmentation_platform/internal/execution/optimization_guide/optimization_guide_segmentation_model_provider.cc
@@ -55,9 +55,15 @@
 void OptimizationGuideSegmentationModelProvider::InitAndFetchModel(
     const ModelUpdatedCallback& model_updated_callback) {
   DCHECK(!model_handler_);
+  absl::optional<optimization_guide::proto::OptimizationTarget> target =
+      SegmentIdToOptimizationTarget(segment_id_);
+  if (!target) {
+    // If the segment ID is not an OptimizationTarget then do not request a
+    // model.
+    return;
+  }
   model_handler_ = std::make_unique<OptimizationGuideSegmentationModelHandler>(
-      model_provider_, background_task_runner_,
-      SegmentIdToOptimizationTarget(segment_id_), model_updated_callback,
+      model_provider_, background_task_runner_, *target, model_updated_callback,
       GetModelFetchConfig());
 }
 
diff --git a/components/segmentation_platform/internal/execution/optimization_guide/segmentation_model_executor_unittest.cc b/components/segmentation_platform/internal/execution/optimization_guide/segmentation_model_executor_unittest.cc
index fd8f146..5d3561b 100644
--- a/components/segmentation_platform/internal/execution/optimization_guide/segmentation_model_executor_unittest.cc
+++ b/components/segmentation_platform/internal/execution/optimization_guide/segmentation_model_executor_unittest.cc
@@ -114,7 +114,7 @@
                               .SetVersion(kModelVersion)
                               .Build();
     opt_guide_model_handler().OnModelUpdated(
-        SegmentIdToOptimizationTarget(kSegmentId), *model_metadata);
+        *SegmentIdToOptimizationTarget(kSegmentId), *model_metadata);
     RunUntilIdle();
   }
 
diff --git a/components/segmentation_platform/internal/segment_id_convertor.cc b/components/segmentation_platform/internal/segment_id_convertor.cc
index a60bb91..7dd18664 100644
--- a/components/segmentation_platform/internal/segment_id_convertor.cc
+++ b/components/segmentation_platform/internal/segment_id_convertor.cc
@@ -4,10 +4,18 @@
 
 #include "components/segmentation_platform/internal/segment_id_convertor.h"
 
+#include "base/check_op.h"
+
 namespace segmentation_platform {
 
-optimization_guide::proto::OptimizationTarget SegmentIdToOptimizationTarget(
-    proto::SegmentId segment_id) {
+absl::optional<optimization_guide::proto::OptimizationTarget>
+SegmentIdToOptimizationTarget(proto::SegmentId segment_id) {
+  DCHECK_LT(static_cast<int>(optimization_guide::proto::OptimizationTarget_MAX),
+            static_cast<int>(proto::SegmentId::MAX_OPTIMIZATION_TARGET));
+  if (static_cast<int>(segment_id) >=
+      static_cast<int>(proto::SegmentId::MAX_OPTIMIZATION_TARGET)) {
+    return absl::nullopt;
+  }
   return static_cast<optimization_guide::proto::OptimizationTarget>(segment_id);
 }
 
diff --git a/components/segmentation_platform/internal/segment_id_convertor.h b/components/segmentation_platform/internal/segment_id_convertor.h
index e0e70e6..743b6b0 100644
--- a/components/segmentation_platform/internal/segment_id_convertor.h
+++ b/components/segmentation_platform/internal/segment_id_convertor.h
@@ -7,12 +7,13 @@
 
 #include "components/optimization_guide/proto/models.pb.h"
 #include "components/segmentation_platform/public/proto/segmentation_platform.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace segmentation_platform {
 
 // Conversion functions between OptimizationTarget and SegmentId.
-optimization_guide::proto::OptimizationTarget SegmentIdToOptimizationTarget(
-    proto::SegmentId segment_id);
+absl::optional<optimization_guide::proto::OptimizationTarget>
+SegmentIdToOptimizationTarget(proto::SegmentId segment_id);
 
 // Conversion functions between OptimizationTarget and SegmentId.
 proto::SegmentId OptimizationTargetToSegmentId(
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
index 46abac7f..994b55e 100644
--- a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
+++ b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
@@ -19,7 +19,6 @@
 #include "components/segmentation_platform/internal/database/mock_ukm_database.h"
 #include "components/segmentation_platform/internal/dummy_ukm_data_manager.h"
 #include "components/segmentation_platform/internal/proto/model_metadata.pb.h"
-#include "components/segmentation_platform/internal/segment_id_convertor.h"
 #include "components/segmentation_platform/internal/segmentation_platform_service_test_base.h"
 #include "components/segmentation_platform/internal/selection/segmentation_result_prefs.h"
 #include "components/segmentation_platform/internal/signals/ukm_observer.h"
diff --git a/components/segmentation_platform/public/proto/segmentation_platform.proto b/components/segmentation_platform/public/proto/segmentation_platform.proto
index 3e6f83a..246105ba 100644
--- a/components/segmentation_platform/public/proto/segmentation_platform.proto
+++ b/components/segmentation_platform/public/proto/segmentation_platform.proto
@@ -9,8 +9,10 @@
 
 package segmentation_platform.proto;
 
-// List of user segment types. Each enum entry should have a corresponding entry
-// in OptimizationTarget.
+// List of user segment types.
+// Any segment that needs a server provided model should have an entry in
+// OptimizationTarget. If the segment only uses default model, then the segment
+// should have a value higher than `MAX_OPTIMIZATION_TARGET`.
 enum SegmentId {
   OPTIMIZATION_TARGET_UNKNOWN = 0;
   // Should only be applied when the page load is predicted to be painful.
@@ -49,11 +51,11 @@
   OPTIMIZATION_TARGET_SEGMENTATION_CHROME_LOW_USER_ENGAGEMENT = 16;
   // Target for segmentation: Determine users who prefer to use Feed.
   OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER = 17;
-  // TODO(ssid): Remove this comment once the migration is final.
-  // DO NOT add new entries here. This is under process of migration from
-  // OptimizationTarget enum. New entries should start from a high value of 1000
-  // if OptimizationTarget does not have a corresponding type.
+  // Add new entries to OptimizationTarget proto.
 
+  // New entries should start from a 1000 if OptimizationTarget does not have a
+  // corresponding type.
+  MAX_OPTIMIZATION_TARGET = 999;
   // Target for price tracking action when shown as a contextual page action.
   CONTEXTUAL_PAGE_ACTIONS_PRICE_TRACKING = 1000;
 };
diff --git a/components/viz/host/gpu_host_impl.cc b/components/viz/host/gpu_host_impl.cc
index 5417369..60e908d2 100644
--- a/components/viz/host/gpu_host_impl.cc
+++ b/components/viz/host/gpu_host_impl.cc
@@ -194,9 +194,8 @@
 void GpuHostImpl::BlockLiveOffscreenContexts() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  for (auto iter = urls_with_live_offscreen_contexts_.begin();
-       iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
-    delegate_->BlockDomainFrom3DAPIs(*iter, gpu::DomainGuilt::kUnknown);
+  for (auto& url : urls_with_live_offscreen_contexts_) {
+    delegate_->BlockDomainFrom3DAPIs(url, gpu::DomainGuilt::kUnknown);
   }
 }
 
diff --git a/components/webauthn/android/BUILD.gn b/components/webauthn/android/BUILD.gn
index 0f9676b..d314075 100644
--- a/components/webauthn/android/BUILD.gn
+++ b/components/webauthn/android/BUILD.gn
@@ -25,7 +25,6 @@
     "java/src/org/chromium/components/webauthn/GetAssertionResponseCallback.java",
     "java/src/org/chromium/components/webauthn/InternalAuthenticator.java",
     "java/src/org/chromium/components/webauthn/IsUvpaaResponseCallback.java",
-    "java/src/org/chromium/components/webauthn/ListCredentials.java",
     "java/src/org/chromium/components/webauthn/MakeCredentialResponseCallback.java",
     "java/src/org/chromium/components/webauthn/WebAuthnBrowserBridge.java",
     "java/src/org/chromium/components/webauthn/WebAuthnCredentialDetails.java",
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/ListCredentials.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/ListCredentials.java
deleted file mode 100644
index 7ab221c..0000000
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/ListCredentials.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.components.webauthn;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Wrapper for an external call to obtain information about discoverable credentials.
- *
- * <p>Provides a static instance of an interface that can be set by an external caller to implement
- * the listCredentials method. That method provides silent enumeration of discoverable platform
- * credentials for a given relying party, in support of WebAuthn Conditional UI.
- */
-public class ListCredentials {
-    /**
-     * Describes a discoverable credential available on the device.
-     */
-    public class DiscoverableCredentialInfo {
-        private String mUserName;
-        private String mUserDisplayName;
-        private byte[] mUserId;
-        private byte[] mCredentialId;
-
-        DiscoverableCredentialInfo(
-                String userName, String userDisplayName, byte[] userId, byte[] credentialId) {
-            mUserName = userName;
-            mUserDisplayName = userDisplayName;
-            mUserId = userId;
-            mCredentialId = credentialId;
-        }
-
-        String getUserName() {
-            return mUserName;
-        }
-
-        String getUserDisplayName() {
-            return mUserDisplayName;
-        }
-
-        byte[] getUserId() {
-            return mUserId;
-        }
-
-        byte[] getCredentialId() {
-            return mCredentialId;
-        }
-    }
-
-    /**
-     * Abstract interface for an embedder to provide a listCredentials method.
-     */
-    public interface AbstractListCredentials {
-        List<DiscoverableCredentialInfo> listCredentials(String rpId);
-    }
-
-    private static AbstractListCredentials sExternalListCredentials;
-
-    /**
-     * Sets an interface that will provide a listCredentials method implementation.
-     *
-     * @param listCredentials the external interface.
-     */
-    public static void setExternalListCredentials(AbstractListCredentials listCredentials) {
-        sExternalListCredentials = listCredentials;
-    }
-
-    /**
-     * Returns a list of discoverable credentials available on this design.
-     *
-     * @param rpId indicates the relying party for which this will return any available
-     * discoverable credentials.
-     */
-    public static List<DiscoverableCredentialInfo> listCredentials(String rpId) {
-        if (sExternalListCredentials != null) {
-            return sExternalListCredentials.listCredentials(rpId);
-        }
-        return new ArrayList<DiscoverableCredentialInfo>();
-    }
-}
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
index 9a588f1..82950c5 100644
--- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
+++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -358,7 +358,7 @@
   std::vector<AttributionTrigger::EventTriggerData> event_triggers;
   event_triggers.reserve(data->event_triggers.size());
 
-  for (const auto& event_trigger : data->event_triggers) {
+  for (auto& event_trigger : data->event_triggers) {
     absl::optional<AttributionFilterData> filters =
         AttributionFilterData::FromTriggerFilterValues(
             std::move(event_trigger->filters->filter_values));
diff --git a/content/browser/direct_sockets/direct_sockets_open_browsertest.cc b/content/browser/direct_sockets/direct_sockets_open_browsertest.cc
index 1e02412..8056bbc5 100644
--- a/content/browser/direct_sockets/direct_sockets_open_browsertest.cc
+++ b/content/browser/direct_sockets/direct_sockets_open_browsertest.cc
@@ -24,6 +24,7 @@
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
@@ -276,6 +277,10 @@
 
     command_line->AppendSwitchASCII(switches::kIsolatedAppOrigins, origin_list);
   }
+
+ private:
+  test::IsolatedAppContentBrowserClient client_;
+  ScopedContentBrowserClientSetting setting{&client_};
 };
 
 IN_PROC_BROWSER_TEST_F(DirectSocketsOpenBrowserTest, OpenTcp_Success_Hostname) {
diff --git a/content/browser/direct_sockets/direct_sockets_tcp_browsertest.cc b/content/browser/direct_sockets/direct_sockets_tcp_browsertest.cc
index 36ce799..af1229c 100644
--- a/content/browser/direct_sockets/direct_sockets_tcp_browsertest.cc
+++ b/content/browser/direct_sockets/direct_sockets_tcp_browsertest.cc
@@ -17,6 +17,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
@@ -39,6 +40,7 @@
 #include "services/network/public/mojom/tcp_socket.mojom.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
 #include "url/gurl.h"
 
 // The tests in this file use the Network Service implementation of
@@ -274,7 +276,6 @@
   void SetUp() override {
     embedded_test_server()->AddDefaultHandlers(GetTestDataFilePath());
     ASSERT_TRUE(embedded_test_server()->Start());
-
     ContentBrowserTest::SetUp();
   }
 
@@ -291,6 +292,9 @@
     return shell()->web_contents()->GetBrowserContext();
   }
 
+ private:
+  test::IsolatedAppContentBrowserClient client_;
+  ScopedContentBrowserClientSetting setting{&client_};
   base::test::ScopedFeatureList feature_list_;
   mojo::Remote<network::mojom::MdnsResponder> mdns_responder_;
   mojo::Remote<network::mojom::TCPServerSocket> tcp_server_socket_;
diff --git a/content/browser/direct_sockets/direct_sockets_test_utils.cc b/content/browser/direct_sockets/direct_sockets_test_utils.cc
index 1189b2f1..4af6afa 100644
--- a/content/browser/direct_sockets/direct_sockets_test_utils.cc
+++ b/content/browser/direct_sockets/direct_sockets_test_utils.cc
@@ -195,6 +195,25 @@
       script.c_str(), token_.ToString().c_str()));
 }
 
+bool IsolatedAppContentBrowserClient::ShouldUrlUseApplicationIsolationLevel(
+    BrowserContext* browser_context,
+    const GURL& url) {
+  return true;
+}
+
+blink::ParsedPermissionsPolicy
+IsolatedAppContentBrowserClient::GetPermissionsPolicyForIsolatedApp(
+    content::BrowserContext* browser_context,
+    const url::Origin& app_origin) {
+  blink::ParsedPermissionsPolicy out;
+  blink::ParsedPermissionsPolicyDeclaration decl(
+      blink::mojom::PermissionsPolicyFeature::kDirectSockets,
+      /*values=*/{app_origin},
+      /*matches_all_origins=*/false, /*matches_opaque_src=*/false);
+  out.push_back(decl);
+  return out;
+}
+
 // misc
 std::string WrapAsync(const std::string& script) {
   DCHECK(!script.empty());
diff --git a/content/browser/direct_sockets/direct_sockets_test_utils.h b/content/browser/direct_sockets/direct_sockets_test_utils.h
index 93f220a..d1b6498 100644
--- a/content/browser/direct_sockets/direct_sockets_test_utils.h
+++ b/content/browser/direct_sockets/direct_sockets_test_utils.h
@@ -192,6 +192,18 @@
 
 std::string WrapAsync(const std::string& script);
 
+// Mock ContentBrowserClient that enableds direct sockets via permissions policy
+// for isolated apps.
+class IsolatedAppContentBrowserClient : public ContentBrowserClient {
+ public:
+  bool ShouldUrlUseApplicationIsolationLevel(BrowserContext* browser_context,
+                                             const GURL& url) override;
+
+  blink::ParsedPermissionsPolicy GetPermissionsPolicyForIsolatedApp(
+      content::BrowserContext* browser_context,
+      const url::Origin& app_origin) override;
+};
+
 }  // namespace content::test
 
 #endif  // CONTENT_BROWSER_DIRECT_SOCKETS_DIRECT_SOCKETS_TEST_UTILS_H_
diff --git a/content/browser/direct_sockets/direct_sockets_udp_browsertest.cc b/content/browser/direct_sockets/direct_sockets_udp_browsertest.cc
index fa7b7c95..bbb4248 100644
--- a/content/browser/direct_sockets/direct_sockets_udp_browsertest.cc
+++ b/content/browser/direct_sockets/direct_sockets_udp_browsertest.cc
@@ -14,6 +14,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
@@ -107,6 +108,8 @@
     return shell()->web_contents()->GetBrowserContext();
   }
 
+  test::IsolatedAppContentBrowserClient client_;
+  ScopedContentBrowserClientSetting setting{&client_};
   base::test::ScopedFeatureList feature_list_;
   mojo::Remote<network::mojom::UDPSocket> server_socket_;
 };
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
index f87601d..4080c423 100644
--- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc
+++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -528,6 +528,15 @@
     return 0;
   }
 
+  double GetPriority(const url::Origin& owner, const std::string& name) {
+    for (const auto& interest_group : GetInterestGroupsForOwner(owner)) {
+      if (interest_group.interest_group.name == name) {
+        return interest_group.interest_group.priority.value();
+      }
+    }
+    return 0;
+  }
+
   absl::optional<GURL> ConvertFencedFrameURNToURL(const GURL& urn_url) {
     TestFencedFrameURLMappingResultObserver observer;
     FencedFrameURLMapping& fenced_frame_urls_map =
@@ -4869,6 +4878,51 @@
       /*guid=*/std::string(), config);
 }
 
+TEST_F(AdAuctionServiceImplTest, SetPriorityAdjustsPriority) {
+  constexpr char kBiddingScript[] = R"(
+function generateBid(
+    interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals,
+    browserSignals) {
+  if (interestGroup.priority !== undefined)
+    throw new Error("Priority should not be in worklet");
+  setPriority(99);
+  return {'ad': 'example', 'bid': 1, 'render': 'https://example.com/render'};
+}
+)";
+
+  constexpr char kDecisionScript[] = R"(
+function scoreAd(
+    adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) {
+  return bid;
+}
+)";
+
+  network_responder_->RegisterScriptResponse(kBiddingUrlPath, kBiddingScript);
+  network_responder_->RegisterScriptResponse(kDecisionUrlPath, kDecisionScript);
+
+  blink::InterestGroup interest_group = CreateInterestGroup();
+  interest_group.bidding_url = kUrlA.Resolve(kBiddingUrlPath);
+  interest_group.priority = 2;
+  interest_group.ads.emplace();
+  blink::InterestGroup::Ad ad(
+      /*render_url=*/GURL("https://example.com/render"),
+      /*metadata=*/absl::nullopt);
+  interest_group.ads->emplace_back(std::move(ad));
+  JoinInterestGroupAndFlush(interest_group);
+  EXPECT_EQ(2, GetPriority(kOriginA, kInterestGroupName));
+
+  blink::AuctionConfig auction_config;
+  auction_config.seller = kOriginA;
+  auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath);
+  auction_config.non_shared_params.interest_group_buyers = {kOriginA};
+  absl::optional<GURL> auction_result =
+      RunAdAuctionAndFlush(std::move(auction_config));
+  ASSERT_NE(auction_result, absl::nullopt);
+  EXPECT_EQ(ConvertFencedFrameURNToURL(*auction_result),
+            GURL("https://example.com/render"));
+  EXPECT_EQ(99, GetPriority(kOriginA, kInterestGroupName));
+}
+
 class AdAuctionServiceImplNumAuctionLimitTest
     : public AdAuctionServiceImplTest {
  public:
diff --git a/content/browser/interest_group/auction_runner.cc b/content/browser/interest_group/auction_runner.cc
index d6c7304..bc634258 100644
--- a/content/browser/interest_group/auction_runner.cc
+++ b/content/browser/interest_group/auction_runner.cc
@@ -647,6 +647,7 @@
         continue;
       if (bidder.interest_group.ads->empty())
         continue;
+      bidder.interest_group.priority.reset();
       bid_states_.emplace_back(BidState());
       bid_states_.back().bidder = std::move(bidder);
     }
@@ -873,6 +874,8 @@
         /*has_bidding_signals_data_version=*/false,
         /*debug_loss_report_url=*/absl::nullopt,
         /*debug_win_report_url=*/absl::nullopt,
+        /*set_priority=*/0,
+        /*has_set_priority=*/false,
         {base::StrCat({bid_state->bidder.interest_group.bidding_url->spec(),
                        " crashed while trying to run generateBid()."})});
     return;
@@ -884,7 +887,8 @@
                         /*bidding_signals_data_version=*/0,
                         /*has_bidding_signals_data_version=*/false,
                         /*debug_loss_report_url=*/absl::nullopt,
-                        /*debug_win_report_url=*/absl::nullopt, errors);
+                        /*debug_win_report_url=*/absl::nullopt,
+                        /*set_priority=*/0, /*has_set_priority=*/false, errors);
 }
 
 void AuctionRunner::Auction::OnGenerateBidComplete(
@@ -894,6 +898,8 @@
     bool has_bidding_signals_data_version,
     const absl::optional<GURL>& debug_loss_report_url,
     const absl::optional<GURL>& debug_win_report_url,
+    double set_priority,
+    bool has_set_priority,
     const std::vector<std::string>& errors) {
   DCHECK(!state->made_bid);
   DCHECK_GT(num_bids_not_sent_to_seller_worklet_, 0);
@@ -906,6 +912,12 @@
   if (has_bidding_signals_data_version)
     maybe_bidding_signals_data_version = bidding_signals_data_version;
 
+  if (has_set_priority) {
+    interest_group_manager_->SetInterestGroupPriority(
+        state->bidder.interest_group.owner, state->bidder.interest_group.name,
+        set_priority);
+  }
+
   errors_.insert(errors_.end(), errors.begin(), errors.end());
 
   // Release the worklet. If it wins the auction, it will be requested again to
diff --git a/content/browser/interest_group/auction_runner.h b/content/browser/interest_group/auction_runner.h
index df369a62..14cce8f 100644
--- a/content/browser/interest_group/auction_runner.h
+++ b/content/browser/interest_group/auction_runner.h
@@ -586,6 +586,8 @@
         bool has_bidding_signals_data_version,
         const absl::optional<GURL>& debug_loss_report_url,
         const absl::optional<GURL>& debug_win_report_url,
+        double set_priority,
+        bool has_set_priority,
         const std::vector<std::string>& errors);
 
     // True if all bid results and the seller script load are complete.
@@ -819,6 +821,11 @@
     // updated after a successful auction, barring rate-limiting.
     std::vector<url::Origin> post_auction_update_owners_;
 
+    // A list of all interest groups that need to have their priority adjusted.
+    // The new rates will be committed after a successful auction.
+    std::vector<std::pair<InterestGroupKey, double>>
+        post_auction_priority_updates_;
+
     // The highest scoring bid so far. Null if no bid has been accepted yet.
     std::unique_ptr<ScoredBid> top_bid_;
     // Number of bidders with the same score as `top_bidder`.
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index 986600a..ea4d4f5a 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -142,6 +142,9 @@
         throw new Error("wrong interestGroupName");
       if (interestGroup.owner !== interestGroupOwner)
         throw new Error("wrong interestGroupOwner");
+      // The actual priority should be hidden from the worklet.
+      if (interestGroup.priority !== undefined)
+        throw new Error("wrong priority: " + interestGroup.priority);
       // None of these tests set a dailyUpdateUrl. Non-empty values are tested
       // by browser tests.
       if ("dailyUpdateUrl" in interestGroup)
@@ -904,6 +907,8 @@
                /*has_bidding_signals_data_version=*/false,
                debug_loss_report_url,
                /*debug_win_report_url=*/absl::nullopt,
+               /*set_priority=*/0,
+               /*has_set_priority=*/false,
                /*errors=*/std::vector<std::string>());
       return;
     }
@@ -914,6 +919,8 @@
              bidding_signals_data_version.value_or(0),
              bidding_signals_data_version.has_value(), debug_loss_report_url,
              debug_win_report_url,
+             /*set_priority=*/0,
+             /*has_set_priority=*/false,
              /*errors=*/std::vector<std::string>());
   }
 
@@ -1685,7 +1692,7 @@
 
     StorageInterestGroup storage_group;
     storage_group.interest_group = blink::InterestGroup(
-        base::Time::Max(), std::move(owner), std::move(name), /*priority=*/0.0,
+        base::Time::Max(), std::move(owner), std::move(name), /*priority=*/1.0,
         std::move(bidding_url),
         /*bidding_wasm_helper_url=*/absl::nullopt,
         /*update_url=*/absl::nullopt, std::move(trusted_bidding_signals_url),
diff --git a/content/browser/interest_group/interest_group_manager_impl.cc b/content/browser/interest_group/interest_group_manager_impl.cc
index 6631696..92e0196 100644
--- a/content/browser/interest_group/interest_group_manager_impl.cc
+++ b/content/browser/interest_group/interest_group_manager_impl.cc
@@ -449,6 +449,14 @@
   max_active_report_requests_ = max_active_report_requests;
 }
 
+void InterestGroupManagerImpl::SetInterestGroupPriority(
+    const url::Origin& owner,
+    const std::string& name,
+    double priority) {
+  impl_.AsyncCall(&InterestGroupStorage::SetInterestGroupPriority)
+      .WithArgs(owner, name, priority);
+}
+
 void InterestGroupManagerImpl::set_max_report_queue_length_for_testing(
     int max_queue_length) {
   max_report_queue_length_ = max_queue_length;
diff --git a/content/browser/interest_group/interest_group_manager_impl.h b/content/browser/interest_group/interest_group_manager_impl.h
index b478ba31..65e47d0e 100644
--- a/content/browser/interest_group/interest_group_manager_impl.h
+++ b/content/browser/interest_group/interest_group_manager_impl.h
@@ -186,6 +186,10 @@
       const url::Origin& frame_origin,
       network::mojom::ClientSecurityStatePtr client_security_state,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+  // Update the interest group priority.
+  void SetInterestGroupPriority(const url::Origin& owner,
+                                const std::string& name,
+                                double priority);
 
   // Clears the InterestGroupPermissionsChecker's cache of the results of
   // .well-known fetches.
diff --git a/content/browser/interest_group/interest_group_storage.cc b/content/browser/interest_group/interest_group_storage.cc
index 31e81717..3c39e71 100644
--- a/content/browser/interest_group/interest_group_storage.cc
+++ b/content/browser/interest_group/interest_group_storage.cc
@@ -1349,6 +1349,28 @@
   return transaction.Commit();
 }
 
+bool DoSetInterestGroupPriority(sql::Database& db,
+                                const url::Origin& owner,
+                                const std::string& name,
+                                double priority) {
+  // clang-format off
+  sql::Statement set_priority_sql(
+      db.GetCachedStatement(SQL_FROM_HERE,
+          "UPDATE interest_groups "
+          "SET priority=? "
+          "WHERE owner=? AND name=?"));
+  // clang-format on
+  if (!set_priority_sql.is_valid()) {
+    DLOG(ERROR) << "SetPriority SQL statement did not compile.";
+    return false;
+  }
+  set_priority_sql.Reset(true);
+  set_priority_sql.BindDouble(0, priority);
+  set_priority_sql.BindString(1, Serialize(owner));
+  set_priority_sql.BindString(2, name);
+  return set_priority_sql.Run();
+}
+
 bool DeleteOldJoins(sql::Database& db, base::Time cutoff) {
   sql::Statement del_join_history(db.GetCachedStatement(
       SQL_FROM_HERE, "DELETE FROM join_history WHERE join_time <= ?"));
@@ -1833,6 +1855,19 @@
   }
 }
 
+void InterestGroupStorage::SetInterestGroupPriority(const url::Origin& owner,
+                                                    const std::string& name,
+                                                    double priority) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!EnsureDBInitialized())
+    return;
+
+  if (!DoSetInterestGroupPriority(*db_, owner, name, priority)) {
+    DLOG(ERROR) << "Could not set interest group priority: "
+                << db_->GetErrorMessage();
+  }
+}
+
 void InterestGroupStorage::PerformDBMaintenance() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   last_maintenance_time_ = base::Time::Now();
diff --git a/content/browser/interest_group/interest_group_storage.h b/content/browser/interest_group/interest_group_storage.h
index 2159e74..fd9113fd 100644
--- a/content/browser/interest_group/interest_group_storage.h
+++ b/content/browser/interest_group/interest_group_storage.h
@@ -121,6 +121,10 @@
   // then apply to all origins.
   void DeleteInterestGroupData(
       const base::RepeatingCallback<bool(const url::Origin&)>& origin_matcher);
+  // Update the interest group priority.
+  void SetInterestGroupPriority(const url::Origin& owner,
+                                const std::string& name,
+                                double priority);
 
   std::vector<StorageInterestGroup> GetAllInterestGroupsUnfilteredForTesting();
 
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index dd1e91e..3983588 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -3195,20 +3195,6 @@
       request->common_params().should_replace_current_entry,
       request->force_new_browsing_instance(), reason);
 
-  TRACE_EVENT_INSTANT(
-      "navigation",
-      "RenderFrameHostManager::GetSiteInstanceForNavigationRequest_Result",
-      ChromeTrackEvent::kSiteInstance,
-      *static_cast<SiteInstanceImpl*>(dest_site_instance.get()),
-      ChromeTrackEvent::kFrameTreeNodeInfo, *frame_tree_node_,
-      [&](perfetto::EventContext ctx) {
-        auto rvh = frame_tree_node_->frame_tree()->GetRenderViewHost(
-            static_cast<SiteInstanceImpl*>(dest_site_instance.get())->group());
-        if (rvh) {
-          auto* event = ctx.event<ChromeTrackEvent>();
-          rvh->WriteIntoTrace(ctx.Wrap(event->set_render_view_host()));
-        }
-      });
   // If the NavigationRequest's dest_site_instance was present but incorrect,
   // then ensure no sensitive state is kept on the request. This can happen for
   // cross-process redirects, error pages, etc.
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc
index cc0b76f5..985cc53 100644
--- a/content/browser/service_worker/service_worker_metrics.cc
+++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -365,7 +365,7 @@
       UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.AbortPaymentEvent.Time", time);
       break;
     case EventType::COOKIE_CHANGE:
-      UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.CookieChangeEvent.Time", time);
+      // Do nothing: the histogram has been removed.
       break;
     case EventType::PERIODIC_SYNC:
       UMA_HISTOGRAM_MEDIUM_TIMES(
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc
index ffee6ee..6205703 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -183,7 +183,7 @@
       std::make_unique<cc::GpuImageDecodeCache>(
           provider_.get(), use_transfer_cache, color_type, kMaxWorkingSetBytes,
           provider_->ContextCapabilities().max_texture_size,
-          cc::PaintImage::kDefaultGeneratorClientId, nullptr));
+          cc::PaintImage::GetNextGeneratorClientId(), nullptr));
   DCHECK(insertion_result.second);
   cache_iterator = insertion_result.first;
   return cache_iterator->second.get();
diff --git a/content/services/auction_worklet/BUILD.gn b/content/services/auction_worklet/BUILD.gn
index 6bd8872..cf1556deb 100644
--- a/content/services/auction_worklet/BUILD.gn
+++ b/content/services/auction_worklet/BUILD.gn
@@ -58,6 +58,8 @@
     "seller_worklet.h",
     "set_bid_bindings.cc",
     "set_bid_bindings.h",
+    "set_priority_bindings.cc",
+    "set_priority_bindings.h",
     "trusted_signals.cc",
     "trusted_signals.h",
     "trusted_signals_request_manager.cc",
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc
index a1faf3b..6842803d 100644
--- a/content/services/auction_worklet/bidder_worklet.cc
+++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -28,6 +28,7 @@
 #include "content/services/auction_worklet/register_ad_beacon_bindings.h"
 #include "content/services/auction_worklet/report_bindings.h"
 #include "content/services/auction_worklet/set_bid_bindings.h"
+#include "content/services/auction_worklet/set_priority_bindings.h"
 #include "content/services/auction_worklet/trusted_signals.h"
 #include "content/services/auction_worklet/trusted_signals_request_manager.h"
 #include "content/services/auction_worklet/worklet_loader.h"
@@ -467,6 +468,7 @@
       browser_signal_top_level_seller_origin.has_value(),
       bidder_worklet_non_shared_params->ads,
       bidder_worklet_non_shared_params->ad_components);
+  SetPriorityBindings set_priority_bindings(v8_helper_.get(), global_template);
 
   // Short lived context, to avoid leaking data at global scope between either
   // repeated calls to this worklet, or to calls to any other worklet.
@@ -653,6 +655,7 @@
                                 bidding_signals_data_version,
                                 for_debugging_only_bindings.TakeLossReportUrl(),
                                 for_debugging_only_bindings.TakeWinReportUrl(),
+                                set_priority_bindings.set_priority(),
                                 std::move(errors_out)));
 }
 
@@ -705,7 +708,7 @@
                      /*bidding_signals_data_version=*/absl::nullopt,
                      /*debug_loss_report_url=*/std::move(debug_loss_report_url),
                      /*debug_win_report_url=*/absl::nullopt,
-                     std::move(error_msgs)));
+                     /*set_priority=*/absl::nullopt, std::move(error_msgs)));
 }
 
 void BidderWorklet::ResumeIfPaused() {
@@ -896,6 +899,7 @@
     absl::optional<uint32_t> bidding_signals_data_version,
     absl::optional<GURL> debug_loss_report_url,
     absl::optional<GURL> debug_win_report_url,
+    absl::optional<double> set_priority,
     std::vector<std::string> error_msgs) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
 
@@ -908,7 +912,8 @@
   std::move(task->callback)
       .Run(std::move(bid), bidding_signals_data_version.value_or(0),
            bidding_signals_data_version.has_value(), debug_loss_report_url,
-           debug_win_report_url, error_msgs);
+           debug_win_report_url, set_priority.value_or(0),
+           set_priority.has_value(), error_msgs);
   generate_bid_tasks_.erase(task);
 }
 
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h
index 8fbc1805..6bb2c20c 100644
--- a/content/services/auction_worklet/bidder_worklet.h
+++ b/content/services/auction_worklet/bidder_worklet.h
@@ -201,6 +201,7 @@
         absl::optional<uint32_t> bidding_signals_data_version,
         absl::optional<GURL> debug_loss_report_url,
         absl::optional<GURL> debug_win_report_url,
+        absl::optional<double> set_priority,
         std::vector<std::string> error_msgs)>;
     using ReportWinCallbackInternal =
         base::OnceCallback<void(absl::optional<GURL> report_url,
@@ -314,6 +315,7 @@
       absl::optional<uint32_t> bidding_signals_data_version,
       absl::optional<GURL> debug_loss_report_url,
       absl::optional<GURL> debug_win_report_url,
+      absl::optional<double> set_priority,
       std::vector<std::string> error_msgs);
 
   // Invokes the `callback` of `task` with the provided values, and removes
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc
index b5d012d..18f5aaf 100644
--- a/content/services/auction_worklet/bidder_worklet_unittest.cc
+++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -183,12 +183,12 @@
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const absl::optional<GURL>& expected_debug_loss_report_url =
           absl::nullopt,
-      const absl::optional<GURL>& expected_debug_win_report_url =
-          absl::nullopt) {
+      const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
+      const absl::optional<double> expected_set_priority = absl::nullopt) {
     RunGenerateBidWithJavascriptExpectingResult(
         CreateGenerateBidScript(raw_return_value), std::move(expected_bid),
         expected_data_version, expected_errors, expected_debug_loss_report_url,
-        expected_debug_win_report_url);
+        expected_debug_win_report_url, expected_set_priority);
   }
 
   // Configures `url_loader_factory_` to return a script with the specified
@@ -200,14 +200,15 @@
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const absl::optional<GURL>& expected_debug_loss_report_url =
           absl::nullopt,
-      const absl::optional<GURL>& expected_debug_win_report_url =
-          absl::nullopt) {
+      const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
+      const absl::optional<double> expected_set_priority = absl::nullopt) {
     SCOPED_TRACE(javascript);
     AddJavascriptResponse(&url_loader_factory_, interest_group_bidding_url_,
                           javascript);
     RunGenerateBidExpectingResult(
         std::move(expected_bid), expected_data_version, expected_errors,
-        expected_debug_loss_report_url, expected_debug_win_report_url);
+        expected_debug_loss_report_url, expected_debug_win_report_url,
+        expected_set_priority);
   }
 
   // Loads and runs a generateBid() script, expecting the provided result.
@@ -217,8 +218,8 @@
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const absl::optional<GURL>& expected_debug_loss_report_url =
           absl::nullopt,
-      const absl::optional<GURL>& expected_debug_win_report_url =
-          absl::nullopt) {
+      const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
+      const absl::optional<double> expected_set_priority = absl::nullopt) {
     auto bidder_worklet = CreateWorkletAndGenerateBid();
 
     EXPECT_EQ(expected_bid.is_null(), bid_.is_null());
@@ -237,6 +238,7 @@
     EXPECT_EQ(expected_debug_loss_report_url, bid_debug_loss_report_url_);
     EXPECT_EQ(expected_debug_win_report_url, bid_debug_win_report_url_);
     EXPECT_EQ(expected_errors, bid_errors_);
+    EXPECT_EQ(expected_set_priority, set_priority_);
   }
 
   // Configures `url_loader_factory_` to return a reportWin() script with the
@@ -397,6 +399,7 @@
                           bool has_data_version,
                           const absl::optional<GURL>& debug_loss_report_url,
                           const absl::optional<GURL>& debug_win_report_url,
+                          double set_priority, bool has_set_priority,
                           const std::vector<std::string>& errors) {
           ADD_FAILURE() << "Callback should not be invoked.";
         }));
@@ -421,14 +424,20 @@
                            bool has_data_version,
                            const absl::optional<GURL>& debug_loss_report_url,
                            const absl::optional<GURL>& debug_win_report_url,
+                           double set_priority,
+                           bool has_set_priority,
                            const std::vector<std::string>& errors) {
     absl::optional<uint32_t> maybe_data_version;
     if (has_data_version)
       maybe_data_version = data_version;
+    absl::optional<double> maybe_set_priority;
+    if (has_set_priority)
+      maybe_set_priority = set_priority;
     bid_ = std::move(bid);
     data_version_ = maybe_data_version;
     bid_debug_loss_report_url_ = debug_loss_report_url;
     bid_debug_win_report_url_ = debug_win_report_url;
+    set_priority_ = maybe_set_priority;
     bid_errors_ = errors;
     load_script_run_loop_->Quit();
   }
@@ -523,6 +532,7 @@
   mojom::BidderWorkletBidPtr bid_;
   absl::optional<GURL> bid_debug_loss_report_url_;
   absl::optional<GURL> bid_debug_win_report_url_;
+  absl::optional<double> set_priority_;
   std::vector<std::string> bid_errors_;
 
   network::TestURLLoaderFactory url_loader_factory_;
@@ -1550,6 +1560,7 @@
                   bool has_data_version,
                   const absl::optional<GURL>& debug_loss_report_url,
                   const absl::optional<GURL>& debug_win_report_url,
+                  double set_priority, bool has_set_priority,
                   const std::vector<std::string>& errors) {
                 EXPECT_EQ(bid_value, bid->bid);
                 EXPECT_EQ(base::NumberToString(bid_value), bid->ad);
@@ -1642,6 +1653,7 @@
                 bool has_data_version,
                 const absl::optional<GURL>& debug_loss_report_url,
                 const absl::optional<GURL>& debug_win_report_url,
+                double set_priority, bool has_set_priority,
                 const std::vector<std::string>& errors) {
               EXPECT_EQ(base::NumberToString(i), bid->ad);
               EXPECT_EQ(i + 1, bid->bid);
@@ -1740,6 +1752,7 @@
                 bool has_data_version,
                 const absl::optional<GURL>& debug_loss_report_url,
                 const absl::optional<GURL>& debug_win_report_url,
+                double set_priority, bool has_set_priority,
                 const std::vector<std::string>& errors) {
               EXPECT_EQ(base::NumberToString(i), bid->ad);
               EXPECT_EQ(i + 1, bid->bid);
@@ -1844,6 +1857,7 @@
                 bool has_data_version,
                 const absl::optional<GURL>& debug_loss_report_url,
                 const absl::optional<GURL>& debug_win_report_url,
+                double set_priority, bool has_set_priority,
                 const std::vector<std::string>& errors) {
               EXPECT_EQ(base::NumberToString(i), bid->ad);
               EXPECT_EQ(i + 1, bid->bid);
@@ -1927,6 +1941,7 @@
                 bool has_data_version,
                 const absl::optional<GURL>& debug_loss_report_url,
                 const absl::optional<GURL>& debug_win_report_url,
+                double set_priority, bool has_set_priority,
                 const std::vector<std::string>& errors) {
               EXPECT_EQ(base::NumberToString(i), bid->ad);
               EXPECT_EQ(i + 1, bid->bid);
@@ -2717,6 +2732,70 @@
       {"https://url.test/ execution of `generateBid` timed out."});
 }
 
+TEST_F(BidderWorkletTest, GenerateBidSetPriority) {
+  // not enough args
+  RunGenerateBidWithJavascriptExpectingResult(
+      CreateGenerateBidScript(
+          R"({ad: "ad", bid:1, render:"https://response.test/" })",
+          /*extra_code=*/R"(
+            setPriority();
+          )"),
+      /*expected_bid=*/mojom::BidderWorkletBidPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      {"https://url.test/:5 Uncaught TypeError: setPriority requires 1 double "
+       "parameter."});
+  // priority not a double
+  RunGenerateBidWithJavascriptExpectingResult(
+      CreateGenerateBidScript(
+          R"({ad: "ad", bid:1, render:"https://response.test/" })",
+          /*extra_code=*/R"(
+            setPriority("string");
+          )"),
+      /*expected_bid=*/mojom::BidderWorkletBidPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      {"https://url.test/:5 Uncaught TypeError: setPriority requires 1 double "
+       "parameter."});
+  // priority not finite
+  RunGenerateBidWithJavascriptExpectingResult(
+      CreateGenerateBidScript(
+          R"({ad: "ad", bid:1, render:"https://response.test/" })",
+          /*extra_code=*/R"(
+            setPriority(0.0/0.0);
+          )"),
+      /*expected_bid=*/mojom::BidderWorkletBidPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      {"https://url.test/:5 Uncaught TypeError: setPriority requires 1 finite "
+       "double parameter."});
+  // priority called twice
+  RunGenerateBidWithJavascriptExpectingResult(
+      CreateGenerateBidScript(
+          R"({ad: "ad", bid:1, render:"https://response.test/" })",
+          /*extra_code=*/R"(
+            setPriority(4);
+            setPriority(4);
+          )"),
+      /*expected_bid=*/mojom::BidderWorkletBidPtr(),
+      /*expected_data_version=*/absl::nullopt,
+      {"https://url.test/:6 Uncaught TypeError: setPriority may be called at "
+       "most once."});
+  // success
+  RunGenerateBidWithJavascriptExpectingResult(
+      CreateGenerateBidScript(
+          R"({ad: "ad", bid:1, render:"https://response.test/" })",
+          /*extra_code=*/R"(
+            setPriority(9.0);
+          )"),
+      /*expected_bid=*/
+      mojom::BidderWorkletBid::New("\"ad\"", 1, GURL("https://response.test/"),
+                                   /*ad_components=*/absl::nullopt,
+                                   base::TimeDelta()),
+      /*expected_data_version=*/absl::nullopt,
+      /*expected_errors=*/{},
+      /*expected_debug_loss_report_url=*/absl::nullopt,
+      /*expected_debug_win_report_url=*/absl::nullopt,
+      /*expected_set_priority=*/9.0);
+}
+
 TEST_F(BidderWorkletTest, ReportWin) {
   RunReportWinWithFunctionBodyExpectingResult(
       "", /*expected_report_url =*/absl::nullopt);
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
index 7ed689f..0f4a825 100644
--- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
+++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -154,6 +154,13 @@
   //  interim reporting API that will be replaced with standardized reporting
   //  APIs once available. It must be a valid HTTPS URL.
   //
+  // `set_priority` The value of the updated priority for this interest group.
+  //  This priority should be applied to the interest group after the auction.
+  //
+  // `has_set_priority` True to indicate the worklet has requested the an
+  //  update to the interest group priority.
+  //  TODO(https://crbug.com/657632): Update when optional integers supported.
+  //
   // `errors` The various error messages to be used for debugging. These are too
   //  sensitive for the renderer to see. There may be errors even when a bid
   //  is offered, and there may be no errors when there's no bid. Includes
@@ -173,6 +180,8 @@
           bool has_bidding_signals_data_version,
           url.mojom.Url? debug_loss_report_url,
           url.mojom.Url? debug_win_report_url,
+          double set_priority,
+          bool has_set_priority,
           array<string> errors);
 
   // Sends pending bidding signals URL requests, if any. Unlike with
diff --git a/content/services/auction_worklet/set_priority_bindings.cc b/content/services/auction_worklet/set_priority_bindings.cc
new file mode 100644
index 0000000..0ddda80
--- /dev/null
+++ b/content/services/auction_worklet/set_priority_bindings.cc
@@ -0,0 +1,78 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/services/auction_worklet/set_priority_bindings.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "content/services/auction_worklet/auction_v8_helper.h"
+#include "gin/converter.h"
+#include "url/gurl.h"
+#include "url/url_constants.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-external.h"
+#include "v8/include/v8-function-callback.h"
+#include "v8/include/v8-template.h"
+
+namespace auction_worklet {
+
+SetPriorityBindings::SetPriorityBindings(
+    AuctionV8Helper* v8_helper,
+    v8::Local<v8::ObjectTemplate> global_template)
+    : v8_helper_(v8_helper) {
+  v8::Local<v8::External> v8_this =
+      v8::External::New(v8_helper_->isolate(), this);
+  v8::Local<v8::FunctionTemplate> v8_template = v8::FunctionTemplate::New(
+      v8_helper_->isolate(), &SetPriorityBindings::SetPriority, v8_this);
+  v8_template->RemovePrototype();
+  global_template->Set(v8_helper_->CreateStringFromLiteral("setPriority"),
+                       v8_template);
+}
+
+SetPriorityBindings::~SetPriorityBindings() = default;
+
+void SetPriorityBindings::SetPriority(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  SetPriorityBindings* bindings = static_cast<SetPriorityBindings*>(
+      v8::External::Cast(*args.Data())->Value());
+  AuctionV8Helper* v8_helper = bindings->v8_helper_;
+
+  double set_priority;
+  if (args.Length() < 1 || args[0].IsEmpty() ||
+      !gin::ConvertFromV8(v8_helper->isolate(), args[0], &set_priority)) {
+    bindings->exception_thrown_ = true;
+    bindings->set_priority_.reset();
+    args.GetIsolate()->ThrowException(
+        v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
+            "setPriority requires 1 double parameter")));
+    return;
+  }
+
+  if (!std::isfinite(set_priority)) {
+    bindings->exception_thrown_ = true;
+    bindings->set_priority_.reset();
+    args.GetIsolate()->ThrowException(
+        v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
+            "setPriority requires 1 finite double parameter")));
+    return;
+  }
+
+  if (bindings->exception_thrown_ || bindings->set_priority_) {
+    bindings->exception_thrown_ = true;
+    bindings->set_priority_.reset();
+    args.GetIsolate()->ThrowException(
+        v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
+            "setPriority may be called at most once")));
+    return;
+  }
+
+  bindings->set_priority_ = set_priority;
+}
+
+}  // namespace auction_worklet
diff --git a/content/services/auction_worklet/set_priority_bindings.h b/content/services/auction_worklet/set_priority_bindings.h
new file mode 100644
index 0000000..42e9471
--- /dev/null
+++ b/content/services/auction_worklet/set_priority_bindings.h
@@ -0,0 +1,48 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SERVICES_AUCTION_WORKLET_SET_PRIORITY_BINDINGS_H_
+#define CONTENT_SERVICES_AUCTION_WORKLET_SET_PRIORITY_BINDINGS_H_
+
+#include "base/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "content/services/auction_worklet/auction_v8_helper.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+#include "v8/include/v8-forward.h"
+
+namespace auction_worklet {
+
+// Class to manage bindings for setting interest group priority. Expected to be
+// used for a short-lived v8::Context. Allows only a single call for to set a
+// priority. On any subequent calls, clears the set priority and throws an
+// exception.
+class SetPriorityBindings {
+ public:
+  // Add report method to `global_template`. The ReportBindings must outlive
+  // the template.
+  SetPriorityBindings(AuctionV8Helper* v8_helper,
+                      v8::Local<v8::ObjectTemplate> global_template);
+  SetPriorityBindings(const SetPriorityBindings&) = delete;
+  SetPriorityBindings& operator=(const SetPriorityBindings&) = delete;
+  ~SetPriorityBindings();
+
+  const absl::optional<double>& set_priority() const { return set_priority_; }
+
+ private:
+  static void SetPriority(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  const raw_ptr<AuctionV8Helper> v8_helper_;
+
+  // This cleared if an exception is thrown.
+  absl::optional<double> set_priority_;
+
+  // Once an exception has been thrown, `set_priority_` will be permanently
+  // cleared.
+  bool exception_thrown_ = false;
+};
+
+}  // namespace auction_worklet
+
+#endif  // CONTENT_SERVICES_AUCTION_WORKLET_SET_PRIORITY_BINDINGS_H_
\ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/fetch_gpu_integration_test_dependencies.py b/content/test/gpu/gpu_tests/fetch_gpu_integration_test_dependencies.py
deleted file mode 100755
index fd71d677..0000000
--- a/content/test/gpu/gpu_tests/fetch_gpu_integration_test_dependencies.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-# 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 os
-import sys
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
-import gpu_path_util  # pylint: disable=wrong-import-position
-
-gpu_path_util.AddDirToPathIfNeeded(gpu_path_util.CATAPULT_DIR, 'devil')
-from devil import devil_env  # pylint: disable=wrong-import-position
-
-
-def main():
-  if len(sys.argv) != 1:
-    print('Usage: {}'.format(sys.argv[0]))
-    return
-  devil_env.config.FetchPath('adb')
-
-
-if __name__ == '__main__':
-  main()
diff --git a/content/test/mock_clipboard_host.cc b/content/test/mock_clipboard_host.cc
index 2c84313..136d030 100644
--- a/content/test/mock_clipboard_host.cc
+++ b/content/test/mock_clipboard_host.cc
@@ -8,11 +8,13 @@
 
 #include "base/containers/contains.h"
 #include "base/notreached.h"
+#include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/base/big_buffer.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_constants.h"
 #include "ui/gfx/codec/png_codec.h"
 
 namespace content {
@@ -42,9 +44,7 @@
   std::move(callback).Run(sequence_number_);
 }
 
-void MockClipboardHost::ReadAvailableTypes(
-    ui::ClipboardBuffer clipboard_buffer,
-    ReadAvailableTypesCallback callback) {
+std::vector<std::u16string> MockClipboardHost::ReadStandardFormatNames() {
   std::vector<std::u16string> types;
   if (!plain_text_.empty())
     types.push_back(u"text/plain");
@@ -58,7 +58,14 @@
     CHECK(!base::Contains(types, it.first));
     types.push_back(it.first);
   }
-  std::move(callback).Run(types);
+  return types;
+}
+
+void MockClipboardHost::ReadAvailableTypes(
+    ui::ClipboardBuffer clipboard_buffer,
+    ReadAvailableTypesCallback callback) {
+  std::vector<std::u16string> types = ReadStandardFormatNames();
+  std::move(callback).Run(std::move(types));
 }
 
 void MockClipboardHost::IsFormatAvailable(blink::mojom::ClipboardFormat format,
@@ -170,10 +177,10 @@
 
 void MockClipboardHost::ReadAvailableCustomAndStandardFormats(
     ReadAvailableCustomAndStandardFormatsCallback callback) {
-  std::vector<std::u16string> format_names;
+  std::vector<std::u16string> format_names = ReadStandardFormatNames();
   for (const auto& item : unsanitized_custom_data_map_)
     format_names.emplace_back(item.first);
-  std::move(callback).Run(format_names);
+  std::move(callback).Run(std::move(format_names));
 }
 
 void MockClipboardHost::ReadUnsanitizedCustomFormat(
@@ -195,7 +202,11 @@
     Reset();
   // Simulate the underlying platform copying this data.
   std::vector<uint8_t> data_copy(data.data(), data.data() + data.size());
-  unsanitized_custom_data_map_[format] = data_copy;
+  // Append the "web " prefix since it is removed by the clipboard writer during
+  // write.
+  std::u16string web_format =
+      base::StrCat({base::ASCIIToUTF16(ui::kWebClipboardFormatPrefix), format});
+  unsanitized_custom_data_map_[web_format] = std::move(data_copy);
 }
 
 #if BUILDFLAG(IS_MAC)
diff --git a/content/test/mock_clipboard_host.h b/content/test/mock_clipboard_host.h
index a6fded3..e4dd210 100644
--- a/content/test/mock_clipboard_host.h
+++ b/content/test/mock_clipboard_host.h
@@ -72,6 +72,8 @@
   void WriteStringToFindPboard(const std::u16string& text) override;
 #endif
  private:
+  std::vector<std::u16string> ReadStandardFormatNames();
+
   mojo::ReceiverSet<blink::mojom::ClipboardHost> receivers_;
   ui::ClipboardSequenceNumberToken sequence_number_;
   std::u16string plain_text_;
diff --git a/docs/workflow/debugging-with-swarming.md b/docs/workflow/debugging-with-swarming.md
index 84d36f14..d0db5b9 100644
--- a/docs/workflow/debugging-with-swarming.md
+++ b/docs/workflow/debugging-with-swarming.md
@@ -70,6 +70,11 @@
 ```
 
 See the `--help` option of `run-swarmed.py` for more details about that script.
+Many flags are converted into dimensions to pass to `mb.py`; see
+[Bot selection criteria](#bot-selection-criteria) for possible values. (Most
+dimensions have the same name as the flag, but `--swarming-os` is just the `os`
+dimension.)
+
 Note you might need `--swarming-os Ubuntu-14.04` if you get an error like,
 `UnboundLocalError: local variable 'dbus_pid' referenced before assignment`.
 
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc
index 06a4e4d..48f7c1a 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc
@@ -94,16 +94,24 @@
     content::NavigationHandle* handle) {
   if (handle->GetFrameTreeNodeId() != frame_tree_node_id_)
     return;
+  if (render_frame_host_)
+    return;
+
+  // It's possible for the navigation to the template HTML document to fail
+  // (e.g. attempting to load a PDF in a fenced frame).
+  if (handle->GetNetErrorCode() != net::OK) {
+    DestroySelf();
+    return;
+  }
+
   // We should've deleted the MimeHandlerViewEmbedder at this point if the frame
   // is sandboxed.
   DCHECK_EQ(network::mojom::WebSandboxFlags::kNone,
             handle->SandboxFlagsToCommit() &
                 network::mojom::WebSandboxFlags::kPlugins);
 
-  if (!render_frame_host_) {
-    render_frame_host_ = handle->GetRenderFrameHost();
-    GetContainerManager()->SetInternalId(internal_id_);
-  }
+  render_frame_host_ = handle->GetRenderFrameHost();
+  GetContainerManager()->SetInternalId(internal_id_);
 }
 
 void MimeHandlerViewEmbedder::DidFinishNavigation(
diff --git a/fuchsia_web/runners/BUILD.gn b/fuchsia_web/runners/BUILD.gn
index 85bdeb3e..dd6f298 100644
--- a/fuchsia_web/runners/BUILD.gn
+++ b/fuchsia_web/runners/BUILD.gn
@@ -9,6 +9,9 @@
 import("//build/config/fuchsia/symbol_archive.gni")
 import("//testing/test.gni")
 
+# Only allow use by targets in this directory unless explicitly specified.
+visibility = [ ":*" ]
+
 declare_args() {
   # Set to a non-zero value to enable remote debugging on that port in WebRunner.
   web_runner_remote_debugging_port = 0
@@ -18,7 +21,6 @@
   header = "buildflags.h"
   flags =
       [ "WEB_RUNNER_REMOTE_DEBUGGING_PORT=$web_runner_remote_debugging_port" ]
-  visibility = [ ":*" ]
 }
 
 # Files common to both cast_runner and web_runner targets.
@@ -48,7 +50,6 @@
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
     "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
   ]
-  visibility = [ ":*" ]
 }
 
 source_set("cast_runner_core") {
@@ -114,7 +115,6 @@
     "//third_party/blink/public/browser",
     "//third_party/blink/public/renderer",
   ]
-  visibility = [ ":*" ]
 }
 
 executable("cast_runner_exe") {
@@ -131,7 +131,6 @@
   ]
 
   data_deps = [ ":cast_runner_core" ]
-  visibility = [ ":*" ]
 }
 
 # web_instance_host's deps, especially //content/public/common, adds these.
@@ -165,13 +164,11 @@
 fuchsia_component("cast_runner_component_v1") {
   manifest = "cast/cast_runner.cmx"
   data_deps = [ ":cast_runner_exe" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_component("cast_runner_component") {
   manifest = "cast/cast_runner.cml"
   data_deps = [ ":cast_runner_exe" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_package("cast_runner_pkg") {
@@ -207,7 +204,6 @@
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sys",
     "//url",
   ]
-  visibility = [ ":*" ]
 }
 
 test("cast_runner_unittests") {
@@ -306,13 +302,11 @@
     "//fuchsia_web/webinstance_host",
     "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp",
   ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_component("web_runner_component") {
   manifest = "web/web_runner.cmx"
   data_deps = [ ":web_runner_exe" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_package("web_runner_pkg") {
diff --git a/fuchsia_web/runners/cast/fidl/BUILD.gn b/fuchsia_web/runners/cast/fidl/BUILD.gn
index 63edb42..9652fcc7 100644
--- a/fuchsia_web/runners/cast/fidl/BUILD.gn
+++ b/fuchsia_web/runners/cast/fidl/BUILD.gn
@@ -4,6 +4,9 @@
 
 import("//third_party/fuchsia-sdk/sdk/build/fidl_library.gni")
 
+# Only allow use by targets in this directory unless explicitly specified.
+visibility = [ ":*" ]
+
 fidl_library("fidl") {
   library_name = "chromium.cast"
 
@@ -23,7 +26,7 @@
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
   ]
 
-  visibility = [
+  visibility += [
     "//chromecast/bindings:*",
     "//chromecast/internal/*",
     "//fuchsia_web/runners:cast_runner_core",
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn
index 17a7b06..3e3934b 100644
--- a/fuchsia_web/webengine/BUILD.gn
+++ b/fuchsia_web/webengine/BUILD.gn
@@ -11,16 +11,17 @@
 import("//third_party/fuchsia-sdk/sdk/build/fidl_library.gni")
 import("//tools/grit/repack.gni")
 
+# Only allow use by targets in this directory unless explicitly specified.
+visibility = [ ":*" ]
+
 config("web_engine_implementation") {
   defines = [ "WEB_ENGINE_IMPLEMENTATION" ]
-  visibility = [ ":*" ]
 }
 
 fidl_library("fidl") {
   library_name = "chromium.internal"
   sources = [ "fidl/dev_tools.fidl" ]
   public_deps = [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web" ]
-  visibility = [ ":*" ]
 }
 
 repack("web_engine_pak") {
@@ -52,7 +53,6 @@
   # TODO(crbug.com/1092804): Move this into ${target_gen_dir} and have a
   # GN SDK fuchsia_resource() rule map it into place in the web_engine package.
   output = "$root_gen_dir/web_engine_common_resources.pak"
-  visibility = [ ":*" ]
 }
 
 foreach(locale, locales_with_pseudolocales) {
@@ -75,7 +75,6 @@
     ]
 
     output = "$root_gen_dir/locales/${locale}.pak"
-    visibility = [ ":*" ]
   }
 }
 
@@ -123,6 +122,9 @@
     "//fuchsia/base:message_port",
     "//fuchsia/base:modular",
     "//fuchsia_web/webengine/mojom",
+
+    # TODO(crbug.com/1081525): Move context_provider to its own target and move
+    # this deps there.
     "//fuchsia_web/webinstance_host",
     "//google_apis",
     "//gpu/command_buffer/service",
@@ -295,25 +297,19 @@
     "web_engine_main_delegate.cc",
     "web_engine_main_delegate.h",
   ]
-  visibility = [ ":*" ]
 }
 
 # TODO(crbug.com/1081525): Rename to features_and_switches or collapse into
 # common. Consider moving these and other files in engine/ to common/ or
 # elsewhere.
 source_set("switches") {
+  visibility += [ "//fuchsia_web/webinstance_host" ]
   deps = [ "//base" ]
-
   sources = [
     "features.h",
     "switches.cc",
     "switches.h",
   ]
-
-  visibility = [
-    ":*",
-    "//fuchsia_web/webinstance_host",
-  ]
 }
 
 executable("web_engine_exe") {
@@ -324,13 +320,11 @@
     "//content/public/app",
   ]
   sources = [ "web_engine_main.cc" ]
-  visibility = [ ":*" ]
 }
 
 source_set("webui_resources") {
   data = [ "$root_gen_dir/ui/resources/webui_generated_resources.pak" ]
   deps = [ "//ui/resources" ]
-  visibility = [ ":*" ]
 }
 
 _web_engine_excluded_files = [
@@ -352,7 +346,6 @@
 fuchsia_component("web_instance_component") {
   manifest = "web_instance.cmx"
   data_deps = [ ":web_engine_exe" ]
-  visibility = [ ":*" ]
 }
 
 # Component definition for the legacy fuchsia.web.ContextProvider service.
@@ -361,7 +354,6 @@
 fuchsia_component("context_provider_component") {
   manifest = "context_provider.cmx"
   data_deps = [ ":web_engine_exe" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_package("web_engine") {
@@ -390,7 +382,6 @@
     "context_provider_with_webui.test-cmx-fragment",
   ]
   output_name = "context_provider_with_webui.cmx"
-  visibility = [ ":*" ]
 }
 
 fuchsia_component("context_provider_with_webui_component") {
@@ -398,7 +389,6 @@
   manifest = "$target_out_dir/context_provider_with_webui.cmx"
   manifest_output_name = "context_provider"
   data_deps = [ ":web_engine_exe" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_package("web_engine_with_webui") {
@@ -415,7 +405,9 @@
   package = ":web_engine_with_webui"
 }
 
+# TODO(crbug.com/1081525): Move to ../common/test.
 source_set("browsertest_core") {
+  visibility += [ "//fuchsia_web/runners:*" ]
   testonly = true
   sources = [
     "test/frame_for_test.cc",
@@ -441,10 +433,6 @@
     "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
     "//ui/ozone",
   ]
-  visibility = [
-    ":*",
-    "//fuchsia_web/runners:*",
-  ]
 }
 
 test("web_engine_browsertests") {
@@ -545,8 +533,6 @@
     "--program",
     "web_engine_unittests__exec",
   ]
-
-  visibility = [ ":*" ]
 }
 
 test("web_engine_unittests") {
@@ -577,7 +563,6 @@
     "//components/url_rewrite/mojom",
     "//content/test:test_support",
     "//fuchsia/base/test:test_support",
-    "//fuchsia_web/webinstance_host",
     "//mojo/core/embedder",
     "//services/media_session/public/mojom",
     "//services/network:network_service",
@@ -654,7 +639,6 @@
   testonly = true
   manifest = "test/web_engine_shell.cmx"
   data_deps = [ ":web_engine_shell_exec" ]
-  visibility = [ ":*" ]
 }
 
 fuchsia_package("web_engine_shell_pkg") {
@@ -696,6 +680,4 @@
     "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
     "//url",
   ]
-
-  visibility = [ ":*" ]
 }
diff --git a/fuchsia_web/webengine/context_provider_impl_unittest.cc b/fuchsia_web/webengine/context_provider_impl_unittest.cc
index 199ed17..6d56a42e 100644
--- a/fuchsia_web/webengine/context_provider_impl_unittest.cc
+++ b/fuchsia_web/webengine/context_provider_impl_unittest.cc
@@ -41,7 +41,6 @@
 #include "build/build_config.h"
 #include "fuchsia_web/webengine/fake_context.h"
 #include "fuchsia_web/webengine/switches.h"
-#include "fuchsia_web/webinstance_host/web_instance_host.h"
 #include "services/network/public/cpp/network_switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -156,7 +155,8 @@
     // CreateContextParams from being mapped.
     // Launch the component via a fake manifest identical to the one used for
     // web instances, but which runs this test executable.
-    EXPECT_EQ(launch_info.url, cr_fuchsia::WebInstanceHost::kComponentUrl);
+    EXPECT_EQ(launch_info.url,
+              "fuchsia-pkg://fuchsia.com/web_engine#meta/web_instance.cmx");
     launch_info.url =
         "fuchsia-pkg://fuchsia.com/web_engine_unittests#meta/"
         "web_engine_unittests_fake_instance.cmx";
diff --git a/fuchsia_web/webengine/mojom/BUILD.gn b/fuchsia_web/webengine/mojom/BUILD.gn
index cadb5ed..3f1ab27 100644
--- a/fuchsia_web/webengine/mojom/BUILD.gn
+++ b/fuchsia_web/webengine/mojom/BUILD.gn
@@ -4,6 +4,9 @@
 
 import("//mojo/public/tools/bindings/mojom.gni")
 
+# Only allow use by the WebEngine implementation.
+visibility = [ "//fuchsia_web/webengine:web_engine_core" ]
+
 mojom("mojom") {
   sources = [ "web_engine_media_resource_provider.mojom" ]
 
diff --git a/fuchsia_web/webinstance_host/BUILD.gn b/fuchsia_web/webinstance_host/BUILD.gn
index 969415cc..0cfce30 100644
--- a/fuchsia_web/webinstance_host/BUILD.gn
+++ b/fuchsia_web/webinstance_host/BUILD.gn
@@ -4,7 +4,22 @@
 
 assert(is_fuchsia)
 
+visibility = []
+
 source_set("webinstance_host") {
+  # Only WebInstance clients should use the host.
+  visibility += [
+    # WebEngine clients that instantiate WebInstances directly.
+    "//fuchsia_web/runners/*",
+    "//fuchsia_web/webengine:web_engine_shell_exec",
+
+    # TODO(crbug.com/1081525): Change to the context_provider target when created.
+    "//fuchsia_web/webengine:web_engine_core",
+
+    # TODO(crbug.com/1081525): Move dependent tests into this directory and
+    # source_sets that have these deps.
+    "//fuchsia_web/webengine:web_engine_integration_tests__exec",
+  ]
   sources = [ "web_instance_host.cc" ]
   public = [ "web_instance_host.h" ]
   deps = [
diff --git a/fuchsia_web/webinstance_host/web_instance_host.cc b/fuchsia_web/webinstance_host/web_instance_host.cc
index 4e0db54..019c285 100644
--- a/fuchsia_web/webinstance_host/web_instance_host.cc
+++ b/fuchsia_web/webinstance_host/web_instance_host.cc
@@ -67,6 +67,11 @@
 
 namespace {
 
+// Production URL for web hosting Component instances.
+// TODO(fxbug.dev/51490): Use a programmatic mechanism to obtain this.
+const char kWebInstanceComponentUrl[] =
+    "fuchsia-pkg://fuchsia.com/web_engine#meta/web_instance.cmx";
+
 // Test-only URL for web hosting Component instances with WebUI resources.
 const char kWebInstanceWithWebUiComponentUrl[] =
     "fuchsia-pkg://fuchsia.com/web_engine_with_webui#meta/web_instance.cmx";
@@ -88,7 +93,7 @@
   constexpr char kFeedbackAnnotationsNamespace[] = "web-engine";
 
   fuchsia_component_support::RegisterProductDataForCrashReporting(
-      WebInstanceHost::kComponentUrl, kCrashProductName);
+      kWebInstanceComponentUrl, kCrashProductName);
 
   fuchsia_component_support::RegisterProductDataForFeedback(
       kFeedbackAnnotationsNamespace);
@@ -523,11 +528,6 @@
 
 }  // namespace
 
-// Production URL for web hosting Component instances.
-// TODO(fxbug.dev/51490): Use a programmatic mechanism to obtain this.
-const char WebInstanceHost::kComponentUrl[] =
-    "fuchsia-pkg://fuchsia.com/web_engine#meta/web_instance.cmx";
-
 WebInstanceHost::WebInstanceHost() {
   // Ensure WebInstance is registered before launching it.
   // TODO(crbug.com/1211174): Replace with a different mechanism when available.
@@ -562,12 +562,12 @@
   launch_args.RemoveSwitch(switches::kContextProvider);
 
   fuchsia::sys::LaunchInfo launch_info;
-  // TODO(1010222): Make kComponentUrl a relative component URL, and
+  // TODO(1010222): Make kWebInstanceComponentUrl a relative component URL, and
   // remove this workaround.
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch("with-webui"))
-    launch_info.url = kWebInstanceWithWebUiComponentUrl;
-  else
-    launch_info.url = kComponentUrl;
+  launch_info.url =
+      base::CommandLine::ForCurrentProcess()->HasSwitch("with-webui")
+          ? kWebInstanceWithWebUiComponentUrl
+          : kWebInstanceComponentUrl;
   launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New();
 
   // Process command-line settings specified in our package config-data.
diff --git a/fuchsia_web/webinstance_host/web_instance_host.h b/fuchsia_web/webinstance_host/web_instance_host.h
index 95bdb0d..e83df3c 100644
--- a/fuchsia_web/webinstance_host/web_instance_host.h
+++ b/fuchsia_web/webinstance_host/web_instance_host.h
@@ -34,9 +34,6 @@
 // TODO(crbug.com/1211174): Remove these requirements.
 class WebInstanceHost {
  public:
-  // Component URL used to launch WebEngine instances to host Contexts.
-  static const char kComponentUrl[];
-
   WebInstanceHost();
   ~WebInstanceHost();
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index e5fdc125..a066195 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -2420,6 +2420,16 @@
   return had_error;
 }
 
+bool GLES2DecoderPassthroughImpl::IsIgnoredCap(GLenum cap) const {
+  switch (cap) {
+    case GL_DEBUG_OUTPUT:
+      return true;
+
+    default:
+      return false;
+  }
+}
+
 bool GLES2DecoderPassthroughImpl::CheckResetStatus() {
   DCHECK(!WasContextLost());
   DCHECK(context_->IsCurrent(nullptr));
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index c5eb8568..342033b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -438,6 +438,8 @@
   GLenum PopError();
   bool FlushErrors();
 
+  bool IsIgnoredCap(GLenum cap) const;
+
   bool IsEmulatedQueryTarget(GLenum target) const;
   error::Error ProcessQueries(bool did_finish);
   void RemovePendingQuery(GLuint service_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 8fce007..9cf1735 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1183,6 +1183,11 @@
 }
 
 error::Error GLES2DecoderPassthroughImpl::DoDisable(GLenum cap) {
+  if (IsIgnoredCap(cap)) {
+    InsertError(GL_INVALID_ENUM, "Invalid cap.");
+    return error::kNoError;
+  }
+
   api()->glDisableFn(cap);
   return error::kNoError;
 }
@@ -1250,6 +1255,11 @@
 }
 
 error::Error GLES2DecoderPassthroughImpl::DoEnable(GLenum cap) {
+  if (IsIgnoredCap(cap)) {
+    InsertError(GL_INVALID_ENUM, "Invalid cap.");
+    return error::kNoError;
+  }
+
   api()->glEnableFn(cap);
   return error::kNoError;
 }
diff --git a/gpu/ipc/common/generate_vulkan_types.py b/gpu/ipc/common/generate_vulkan_types.py
index 782a630..db89db1 100755
--- a/gpu/ipc/common/generate_vulkan_types.py
+++ b/gpu/ipc/common/generate_vulkan_types.py
@@ -531,17 +531,17 @@
 
   mojom_file_name = "vulkan_types.mojom"
   mojom_file = open(
-      os.path.join(output_dir, mojom_file_name), 'w')
+      os.path.join(output_dir, mojom_file_name), 'w', newline='')
   GenerateMojom(mojom_file)
   mojom_file.close()
   ClangFormat(mojom_file.name)
 
   traits_header_file_name = "vulkan_types_mojom_traits.h"
   traits_header_file = \
-      open(os.path.join(output_dir, traits_header_file_name), 'w')
+      open(os.path.join(output_dir, traits_header_file_name), 'w', newline='')
   traits_source_file_name = "vulkan_types_mojom_traits.cc"
   traits_source_file = \
-      open(os.path.join(output_dir, traits_source_file_name), 'w')
+      open(os.path.join(output_dir, traits_source_file_name), 'w', newline='')
   GenerateTraitsFile(traits_header_file, traits_source_file)
   traits_header_file.close()
   ClangFormat(traits_header_file.name)
@@ -550,7 +550,7 @@
 
   typemap_file_name = "generated_vulkan_type_mappings.gni"
   typemap_file = open(
-      os.path.join(output_dir, typemap_file_name), 'w')
+      os.path.join(output_dir, typemap_file_name), 'w', newline='')
   GenerateTypemapFile(typemap_file)
   typemap_file.close()
 
diff --git a/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py b/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py
index b553794..8e14bc8 100755
--- a/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py
+++ b/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py
@@ -1,14 +1,15 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright 2014 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Code generator for khronos_glcts tests."""
 
+import argparse
 import os
 import re
 import sys
-import argparse
+import typing
 
 TEST_DEF_TEMPLATE = """
 TEST(KhronosGLCTSTest, %(gname)s) {
@@ -32,7 +33,7 @@
   ],
 }
 
-def ReadFileAsLines(filename):
+def ReadFileAsLines(filename: str) -> typing.Generator[str, None, None]:
   """
     Reads a file, yielding each non-blank line
     and lines that don't begin with #
@@ -44,13 +45,13 @@
     if len(line) > 0 and not line.startswith("#"):
       yield line
 
-def ReadRunFile(run_file):
+def ReadRunFile(run_file: str) -> typing.List[str]:
   """
     Find all .test tests in a .run file and return their paths.
     If the .run file contains another .run file, then that is inspected
     too.
   """
-  tests = list()
+  tests = []
   base_dir = os.path.dirname(run_file)
   for line in ReadFileAsLines(run_file):
     _, ext = os.path.splitext(line)
@@ -59,10 +60,10 @@
     elif ext == ".run":
       tests += ReadRunFile(os.path.join(base_dir, line))
     else:
-      raise ValueError, "Unexpected line '%s' in '%s'" % (line, run_file)
+      raise ValueError("Unexpected line '%s' in '%s'" % (line, run_file))
   return tests
 
-def GenerateTests(run_files, output):
+def GenerateTests(run_files: typing.List[str], output: typing.IO) -> None:
   """
     Generates code for khronos_glcts_test test-cases that are
     listed in the run_files.
@@ -94,7 +95,7 @@
         })
     output.write("\n");
 
-def main():
+def main() -> int:
   """This is the main function."""
   parser = argparse.ArgumentParser()
   parser.add_argument("--outdir", default = ".")
@@ -103,7 +104,7 @@
   args = parser.parse_args()
 
   output = open(
-    os.path.join(args.outdir, "khronos_glcts_test_autogen.cc"), "wb")
+    os.path.join(args.outdir, "khronos_glcts_test_autogen.cc"), "w")
 
   try:
     GenerateTests(args.run_files, output)
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 97ad1a8..d4569898 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -8186,11 +8186,10 @@
       }
       properties:
         '{'
-        '  "$build/goma": {'
-        '    "enable_ats": true,'
-        '    "rpc_extra_params": "?prod",'
-        '    "server_host": "goma.chromium.org",'
-        '    "use_luci_auth": true'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-trusted",'
+        '    "jobs": 80,'
+        '    "metrics_project": "chromium-reclient-metrics"'
         '  },'
         '  "$recipe_engine/resultdb/test_presentation": {'
         '    "column_keys": [],'
@@ -27555,7 +27554,7 @@
         '  "led_builder_is_bootstrapped": true,'
         '  "recipe": "chromium"'
         '}'
-      execution_timeout_secs: 43200
+      execution_timeout_secs: 50400
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
@@ -54544,12 +54543,11 @@
     builders {
       name: "fuchsia-binary-size"
       swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:8"
+      dimensions: "builder:fuchsia-binary-size"
+      dimensions: "cores:16"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.try"
-      dimensions: "ssd:0"
       exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
@@ -54567,6 +54565,7 @@
         '  },'
         '  "$build/goma": {'
         '    "enable_ats": true,'
+        '    "jobs": 150,'
         '    "rpc_extra_params": "?prod",'
         '    "server_host": "goma.chromium.org",'
         '    "use_luci_auth": true'
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
index b0ded28..8e63ae2 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -317,6 +317,9 @@
     triggering_policy = scheduler.greedy_batching(
         max_concurrent_invocations = 3,
     ),
+    goma_backend = None,
+    reclient_jobs = rbe_jobs.LOW_JOBS_FOR_CI,
+    reclient_instance = rbe_instance.DEFAULT,
 )
 
 ci.builder(
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 1472fa7..a3fd371f 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1066,7 +1066,7 @@
     reclient_rewrapper_env = {"RBE_compare": "true"},
     reclient_ensure_verified = True,
     description_html = "verify artifacts. should be removed after the migration. crbug.com/1235218",
-    execution_timeout = 12 * time.hour,
+    execution_timeout = 14 * time.hour,
 )
 
 ci.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
index 34235c4..fab55880 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
@@ -46,8 +46,10 @@
 try_.builder(
     name = "fuchsia-binary-size",
     branch_selector = branches.FUCHSIA_LTS_MILESTONE,
-    builderless = True,
+    builderless = not settings.is_main,
+    cores = 16,
     executable = "recipe:binary_size_fuchsia_trybot",
+    goma_jobs = goma.jobs.J150,
     properties = {
         "$build/binary_size": {
             "analyze_targets": [
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index fc2ca15d..4746b5ef 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -448,6 +448,9 @@
      flag_descriptions::kWebPageAlternativeTextZoomName,
      flag_descriptions::kWebPageAlternativeTextZoomDescription,
      flags_ui::kOsIos, FEATURE_VALUE_TYPE(web::kWebPageAlternativeTextZoom)},
+    {"webpage-text-zoom-ipad", flag_descriptions::kWebPageTextZoomIPadName,
+     flag_descriptions::kWebPageTextZoomIPadDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(web::kWebPageTextZoomIPad)},
     {"toolbar-container", flag_descriptions::kToolbarContainerName,
      flag_descriptions::kToolbarContainerDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(toolbar_container::kToolbarContainerEnabled)},
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 62fe7df..2aff901 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -696,6 +696,10 @@
 const char kWebPageAlternativeTextZoomDescription[] =
     "When enabled, switches the method used to zoom web pages.";
 
+const char kWebPageTextZoomIPadName[] = "Enable text zoom on iPad";
+const char kWebPageTextZoomIPadDescription[] =
+    "When enabled, text zoom works again on iPad";
+
 // Please insert your name/description above in alphabetical order.
 
 }  // namespace flag_descriptions
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index cb7be79..d249029 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -627,6 +627,10 @@
 extern const char kWebPageAlternativeTextZoomName[];
 extern const char kWebPageAlternativeTextZoomDescription[];
 
+// Title and description for the flag to (re)-enable text zoom on iPad.
+extern const char kWebPageTextZoomIPadName[];
+extern const char kWebPageTextZoomIPadDescription[];
+
 // Please add names and descriptions above in alphabetical order.
 
 }  // namespace flag_descriptions
diff --git a/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm b/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm
index b108ef4..fc3f8fc4 100644
--- a/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm
+++ b/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm
@@ -19,7 +19,8 @@
 }
 
 bool IsTextZoomEnabled() {
-  return ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET;
+  return base::FeatureList::IsEnabled(web::kWebPageTextZoomIPad) ||
+         ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET;
 }
 
 }  // namespace provider
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
index 79a7da2c..182d19810 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
@@ -7,6 +7,8 @@
     "content_suggestions_gesture_commands.h",
     "content_suggestions_header_item.h",
     "content_suggestions_header_item.mm",
+    "content_suggestions_module_container.h",
+    "content_suggestions_module_container.mm",
     "content_suggestions_most_visited_action_cell.h",
     "content_suggestions_most_visited_action_cell.mm",
     "content_suggestions_most_visited_action_item.h",
@@ -56,6 +58,7 @@
     "//ios/chrome/browser/ui/content_suggestions:constants",
     "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
     "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui_util",
+    "//ios/chrome/browser/ui/content_suggestions:feature_flags",
     "//ios/chrome/browser/ui/content_suggestions:public",
     "//ios/chrome/browser/ui/content_suggestions/identifier",
     "//ios/chrome/browser/ui/icons:symbols",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.h
new file mode 100644
index 0000000..88afe41
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.h
@@ -0,0 +1,25 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MODULE_CONTAINER_H_
+#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MODULE_CONTAINER_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
+
+// Container View for a module in the Content Suggestions.
+@interface ContentSuggestionsModuleContainer : UIView
+
+// Initializes the view with a `contentView` content that is showing the Content
+// Suggestions `type`.
+- (instancetype)initWithContentView:(UIView*)contentView
+                         moduleType:(ContentSuggestionsModuleType)type;
+
+- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
+- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MODULE_CONTAINER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm
new file mode 100644
index 0000000..b9ef8bd9
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm
@@ -0,0 +1,110 @@
+// 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/content_suggestions/cells/content_suggestions_module_container.h"
+
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// The horizontal inset of the contents to this container when there is a title.
+const float kContentHorizontalInset = 16.0f;
+
+// The top inset of the title label to this container.
+const float kTitleTopInset = -11.0f;
+
+// The corner radius of this container.
+const float kCornerRadius = 10;
+
+// The shadow radius of this container.
+const float kShadowRadius = 60;
+
+// The shadow opacity of this container.
+const float kShadowOpacity = 0.06;
+
+// The shadow offset of this container.
+const CGSize kShadowOffset = CGSizeMake(0, 20);
+
+}  // namespace
+
+@interface ContentSuggestionsModuleContainer ()
+
+@property(nonatomic, assign) ContentSuggestionsModuleType type;
+
+@end
+
+@implementation ContentSuggestionsModuleContainer
+
+- (instancetype)initWithContentView:(UIView*)contentView
+                         moduleType:(ContentSuggestionsModuleType)type {
+  self = [super initWithFrame:CGRectZero];
+  if (self) {
+    _type = type;
+
+    self.layer.cornerRadius = kCornerRadius;
+    self.backgroundColor = [UIColor colorNamed:kBackgroundColor];
+    self.layer.shadowColor = [UIColor blackColor].CGColor;
+    self.layer.shadowOffset = kShadowOffset;
+    self.layer.shadowRadius = kShadowRadius;
+    self.layer.shadowOpacity = kShadowOpacity;
+
+    contentView.translatesAutoresizingMaskIntoConstraints = NO;
+    [self addSubview:contentView];
+
+    NSString* titleString = [self titleString];
+    if ([titleString length] > 0) {
+      UILabel* title = [[UILabel alloc] init];
+      title.text = [self titleString];
+      title.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
+      title.textColor = [UIColor colorNamed:kTextSecondaryColor];
+      title.translatesAutoresizingMaskIntoConstraints = NO;
+      [self addSubview:title];
+      [NSLayoutConstraint activateConstraints:@[
+        // Title constraints.
+        [title.leadingAnchor constraintEqualToAnchor:self.leadingAnchor
+                                            constant:kContentHorizontalInset],
+        [title.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+        [self.topAnchor constraintEqualToAnchor:title.topAnchor
+                                       constant:kTitleTopInset],
+        // contentView constraints.
+        [contentView.leadingAnchor
+            constraintEqualToAnchor:self.leadingAnchor
+                           constant:kContentHorizontalInset],
+        [contentView.trailingAnchor
+            constraintEqualToAnchor:self.trailingAnchor
+                           constant:-kContentHorizontalInset],
+        [contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
+        [contentView.topAnchor constraintEqualToAnchor:title.bottomAnchor],
+      ]];
+    } else {
+      [NSLayoutConstraint activateConstraints:@[
+        [contentView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
+        [contentView.trailingAnchor
+            constraintEqualToAnchor:self.trailingAnchor],
+        [contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
+        [contentView.topAnchor constraintEqualToAnchor:self.topAnchor],
+      ]];
+    }
+  }
+  return self;
+}
+
+// Returns the title string for the module, empty string if there should be no
+// title.
+- (NSString*)titleString {
+  switch (self.type) {
+    case ContentSuggestionsModuleTypeShortcuts:
+      return @"Shortcuts";
+    case ContentSuggestionsModuleTypeMostVisited:
+      return @"Frequently Visited";
+    case ContentSuggestionsModuleTypeReturnToRecentTab:
+      return @"";
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
index 043fec9b..6ef8c86 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
@@ -7,6 +7,13 @@
 
 #import <UIKit/UIKit.h>
 
+// Enum specifying the type of Content Suggestions a module is showing.
+typedef NS_ENUM(int32_t, ContentSuggestionsModuleType) {
+  ContentSuggestionsModuleTypeMostVisited,
+  ContentSuggestionsModuleTypeShortcuts,
+  ContentSuggestionsModuleTypeReturnToRecentTab,
+};
+
 // Represents the content suggestions collection view.
 extern NSString* const kContentSuggestionsCollectionIdentifier;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 2301051..2ece824 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -9,6 +9,7 @@
 #include "base/metrics/user_metrics_action.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.h"
+#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.h"
@@ -42,6 +43,17 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+// The width of the modules.
+const int kModuleWidth = 343;
+
+// The height of the modules;
+const int kModuleHeight = 139;
+
+// The spacing between the modules.
+const float kModuleVerticalSpacing = 16.0f;
+}  // namespace
+
 @interface ContentSuggestionsViewController () <
     UIGestureRecognizerDelegate,
     ContentSuggestionsSelectionActions>
@@ -88,32 +100,65 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
 
-  self.view.backgroundColor = ntp_home::kNTPBackgroundColor();
+  if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+    self.view.backgroundColor = [UIColor clearColor];
+  } else {
+    self.view.backgroundColor = ntp_home::kNTPBackgroundColor();
+  }
   self.view.accessibilityIdentifier = kContentSuggestionsCollectionIdentifier;
 
   self.verticalStackView = [[UIStackView alloc] init];
   self.verticalStackView.translatesAutoresizingMaskIntoConstraints = NO;
+  if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+    self.verticalStackView.spacing = kModuleVerticalSpacing;
+  }
   self.verticalStackView.axis = UILayoutConstraintAxisVertical;
   // A centered alignment will ensure the views are centered.
   self.verticalStackView.alignment = UIStackViewAlignmentCenter;
   // A fill distribution allows for the custom spacing between elements and
   // height/width configurations for each row.
   self.verticalStackView.distribution = UIStackViewDistributionFill;
-  [self.view addSubview:_verticalStackView];
-  AddSameConstraints(self.view, _verticalStackView);
+  [self.view addSubview:self.verticalStackView];
+  if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+    // Add bottom spacing to last module by applying it after
+    // `_verticalStackView`.
+    [NSLayoutConstraint activateConstraints:@[
+      [self.verticalStackView.leadingAnchor
+          constraintEqualToAnchor:self.view.leadingAnchor],
+      [self.verticalStackView.trailingAnchor
+          constraintEqualToAnchor:self.view.trailingAnchor],
+      [self.verticalStackView.topAnchor
+          constraintEqualToAnchor:self.view.topAnchor],
+      [self.verticalStackView.bottomAnchor
+          constraintEqualToAnchor:self.view.bottomAnchor
+                         constant:-kModuleVerticalSpacing]
+    ]];
+  } else {
+    AddSameConstraints(self.view, self.verticalStackView);
+  }
 
   CGFloat horizontalSpacing =
       ContentSuggestionsTilesHorizontalSpacing(self.traitCollection);
   if (self.returnToRecentTabTile) {
-    [self addUIElement:self.returnToRecentTabTile
-        withCustomBottomSpacing:content_suggestions::
-                                    kReturnToRecentTabSectionBottomMargin];
+    UIView* parentView = self.returnToRecentTabTile;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      ContentSuggestionsModuleContainer* returnToRecentTabContainer =
+          [[ContentSuggestionsModuleContainer alloc]
+              initWithContentView:self.returnToRecentTabTile
+                       moduleType:
+                           ContentSuggestionsModuleTypeReturnToRecentTab];
+      parentView = returnToRecentTabContainer;
+      [self.verticalStackView addArrangedSubview:returnToRecentTabContainer];
+    } else {
+      [self addUIElement:self.returnToRecentTabTile
+          withCustomBottomSpacing:content_suggestions::
+                                      kReturnToRecentTabSectionBottomMargin];
+    }
     CGFloat cardWidth = content_suggestions::searchFieldWidth(
         self.view.bounds.size.width, self.traitCollection);
     [NSLayoutConstraint activateConstraints:@[
-      [self.returnToRecentTabTile.widthAnchor
-          constraintEqualToConstant:cardWidth],
-      [self.returnToRecentTabTile.heightAnchor
+      [parentView.widthAnchor constraintEqualToConstant:cardWidth],
+      [parentView.heightAnchor
           constraintEqualToConstant:kReturnToRecentTabSize.height]
     ]];
   }
@@ -128,31 +173,55 @@
       [self.whatsNewView.heightAnchor constraintEqualToConstant:size.height]
     ]];
   }
-  if (self.mostVisitedViews) {
+  if (IsContentSuggestionsUIModuleRefreshEnabled() || self.mostVisitedViews) {
     self.mostVisitedStackView = [[UIStackView alloc] init];
     self.mostVisitedStackView.axis = UILayoutConstraintAxisHorizontal;
-    self.mostVisitedStackView.alignment = UIStackViewAlignmentTop;
     self.mostVisitedStackView.distribution = UIStackViewDistributionFillEqually;
     self.mostVisitedStackView.spacing = horizontalSpacing;
-    [self addUIElement:self.mostVisitedStackView
-        withCustomBottomSpacing:kMostVisitedBottomMargin];
+
+    UIView* parentView = self.mostVisitedStackView;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      self.mostVisitedStackView.backgroundColor =
+          ntp_home::kNTPBackgroundColor();
+      self.mostVisitedStackView.alignment = UIStackViewAlignmentCenter;
+      ContentSuggestionsModuleContainer* mostVisitedContainer =
+          [[ContentSuggestionsModuleContainer alloc]
+              initWithContentView:self.mostVisitedStackView
+                       moduleType:ContentSuggestionsModuleTypeMostVisited];
+      parentView = mostVisitedContainer;
+      [self.verticalStackView addArrangedSubview:mostVisitedContainer];
+    } else {
+      self.mostVisitedStackView.alignment = UIStackViewAlignmentTop;
+      [self addUIElement:self.mostVisitedStackView
+          withCustomBottomSpacing:kMostVisitedBottomMargin];
+    }
     CGFloat width =
-        MostVisitedTilesContentHorizontalSpace(self.traitCollection);
-    CGSize size =
-        MostVisitedCellSize(self.traitCollection.preferredContentSizeCategory);
+        IsContentSuggestionsUIModuleRefreshEnabled()
+            ? kModuleWidth
+            : MostVisitedTilesContentHorizontalSpace(self.traitCollection);
+    CGFloat height =
+        IsContentSuggestionsUIModuleRefreshEnabled()
+            ? kModuleHeight
+            : MostVisitedCellSize(
+                  self.traitCollection.preferredContentSizeCategory)
+                  .height;
     [NSLayoutConstraint activateConstraints:@[
-      [self.mostVisitedStackView.widthAnchor constraintEqualToConstant:width],
-      [self.mostVisitedStackView.heightAnchor
-          constraintEqualToConstant:size.height]
+      [parentView.widthAnchor constraintEqualToConstant:width],
+      [parentView.heightAnchor constraintEqualToConstant:height]
     ]];
     [self populateMostVisitedModule];
   }
   if (self.shortcutsViews) {
     self.shortcutsStackView = [[UIStackView alloc] init];
     self.shortcutsStackView.axis = UILayoutConstraintAxisHorizontal;
-    self.shortcutsStackView.alignment = UIStackViewAlignmentTop;
     self.shortcutsStackView.distribution = UIStackViewDistributionFillEqually;
     self.shortcutsStackView.spacing = horizontalSpacing;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      self.shortcutsStackView.alignment = UIStackViewAlignmentCenter;
+      self.shortcutsStackView.backgroundColor = ntp_home::kNTPBackgroundColor();
+    } else {
+      self.shortcutsStackView.alignment = UIStackViewAlignmentTop;
+    }
     NSUInteger index = 0;
     for (ContentSuggestionsShortcutTileView* view in self.shortcutsViews) {
       view.accessibilityIdentifier = [NSString
@@ -168,16 +237,31 @@
       index++;
     }
 
-    [self addUIElement:self.shortcutsStackView
-        withCustomBottomSpacing:kMostVisitedBottomMargin];
+    UIView* parentView = self.shortcutsStackView;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      ContentSuggestionsModuleContainer* shortcutsContainer =
+          [[ContentSuggestionsModuleContainer alloc]
+              initWithContentView:self.shortcutsStackView
+                       moduleType:ContentSuggestionsModuleTypeShortcuts];
+      parentView = shortcutsContainer;
+      [self.verticalStackView addArrangedSubview:shortcutsContainer];
+    } else {
+      [self addUIElement:self.shortcutsStackView
+          withCustomBottomSpacing:kMostVisitedBottomMargin];
+    }
     CGFloat width =
-        MostVisitedTilesContentHorizontalSpace(self.traitCollection);
-    CGSize size =
-        MostVisitedCellSize(self.traitCollection.preferredContentSizeCategory);
+        IsContentSuggestionsUIModuleRefreshEnabled()
+            ? kModuleWidth
+            : MostVisitedTilesContentHorizontalSpace(self.traitCollection);
+    CGFloat height =
+        IsContentSuggestionsUIModuleRefreshEnabled()
+            ? kModuleHeight
+            : MostVisitedCellSize(
+                  self.traitCollection.preferredContentSizeCategory)
+                  .height;
     [NSLayoutConstraint activateConstraints:@[
-      [self.shortcutsStackView.widthAnchor constraintEqualToConstant:width],
-      [self.shortcutsStackView.heightAnchor
-          constraintEqualToConstant:size.height]
+      [parentView.widthAnchor constraintEqualToConstant:width],
+      [parentView.heightAnchor constraintEqualToConstant:height]
     ]];
   }
 }
@@ -214,18 +298,29 @@
   // If the Content Suggestions is already shown, add the Return to Recent Tab
   // tile to the StackView.
   if ([[self.verticalStackView arrangedSubviews] count]) {
-    [self.verticalStackView insertArrangedSubview:self.returnToRecentTabTile
-                                          atIndex:0];
-    [self.verticalStackView
-        setCustomSpacing:content_suggestions::
-                             kReturnToRecentTabSectionBottomMargin
-               afterView:self.returnToRecentTabTile];
+    UIView* parentView = self.returnToRecentTabTile;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      ContentSuggestionsModuleContainer* returnToRecentTabContainer =
+          [[ContentSuggestionsModuleContainer alloc]
+              initWithContentView:self.returnToRecentTabTile
+                       moduleType:
+                           ContentSuggestionsModuleTypeReturnToRecentTab];
+      parentView = returnToRecentTabContainer;
+      [self.verticalStackView insertArrangedSubview:returnToRecentTabContainer
+                                            atIndex:0];
+    } else {
+      [self.verticalStackView insertArrangedSubview:self.returnToRecentTabTile
+                                            atIndex:0];
+      [self.verticalStackView
+          setCustomSpacing:content_suggestions::
+                               kReturnToRecentTabSectionBottomMargin
+                 afterView:self.returnToRecentTabTile];
+    }
     CGFloat cardWidth = content_suggestions::searchFieldWidth(
         self.view.bounds.size.width, self.traitCollection);
     [NSLayoutConstraint activateConstraints:@[
-      [self.returnToRecentTabTile.widthAnchor
-          constraintEqualToConstant:cardWidth],
-      [self.returnToRecentTabTile.heightAnchor
+      [parentView.widthAnchor constraintEqualToConstant:cardWidth],
+      [parentView.heightAnchor
           constraintEqualToConstant:kReturnToRecentTabSize.height]
     ]];
     [self.audience returnToRecentTabWasAdded];
@@ -241,8 +336,13 @@
 }
 
 - (void)hideReturnToRecentTabTile {
+  UIView* moduleView = [self.returnToRecentTabTile superview];
   [self.returnToRecentTabTile removeFromSuperview];
   self.returnToRecentTabTile = nil;
+  if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+    // Remove module container.
+    [moduleView removeFromSuperview];
+  }
 }
 
 - (void)showWhatsNewViewWithConfig:(ContentSuggestionsWhatsNewItem*)config {
@@ -325,20 +425,29 @@
 - (CGFloat)contentSuggestionsHeight {
   CGFloat height = 0;
   if ([self.mostVisitedViews count] > 0) {
-    height += MostVisitedCellSize(
-                  UIApplication.sharedApplication.preferredContentSizeCategory)
-                  .height +
-              kMostVisitedBottomMargin;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      height += kModuleHeight + kModuleVerticalSpacing;
+    } else {
+      height +=
+          MostVisitedCellSize(
+              UIApplication.sharedApplication.preferredContentSizeCategory)
+              .height +
+          kMostVisitedBottomMargin;
+    }
   }
   if ([self.shortcutsViews count] > 0) {
-    height += MostVisitedCellSize(
-                  UIApplication.sharedApplication.preferredContentSizeCategory)
-                  .height +
-              kMostVisitedBottomMargin;
+    if (IsContentSuggestionsUIModuleRefreshEnabled()) {
+      height += kModuleHeight + kModuleVerticalSpacing;
+    } else {
+      height +=
+          MostVisitedCellSize(
+              UIApplication.sharedApplication.preferredContentSizeCategory)
+              .height +
+          kMostVisitedBottomMargin;
+    }
   }
   if (self.returnToRecentTabTile) {
-    height += (kReturnToRecentTabSize.height +
-               content_suggestions::kReturnToRecentTabSectionBottomMargin);
+    height += (kReturnToRecentTabSize.height + kModuleVerticalSpacing);
   }
   if (self.whatsNewView) {
     height += MostVisitedCellSize(
@@ -424,7 +533,8 @@
 - (void)populateMostVisitedModule {
   // If viewDidLoad has been called before the first valid Most Visited Tiles
   // are available, construct |mostVisitedStackView|.
-  if (self.verticalStackView && !self.mostVisitedStackView) {
+  if (!IsContentSuggestionsUIModuleRefreshEnabled() && self.verticalStackView &&
+      !self.mostVisitedStackView) {
     self.mostVisitedStackView = [[UIStackView alloc] init];
     self.mostVisitedStackView.axis = UILayoutConstraintAxisHorizontal;
     self.mostVisitedStackView.alignment = UIStackViewAlignmentTop;
diff --git a/ios/chrome/browser/ui/follow/BUILD.gn b/ios/chrome/browser/ui/follow/BUILD.gn
index c0c5dfbe..f0d0c2f 100644
--- a/ios/chrome/browser/ui/follow/BUILD.gn
+++ b/ios/chrome/browser/ui/follow/BUILD.gn
@@ -40,11 +40,14 @@
   deps = [
     ":first_follow_ui",
     ":follow",
+    "//ios/chrome/browser/discover_feed",
+    "//ios/chrome/browser/discover_feed:discover_feed_factory",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/main:public",
     "//ios/chrome/browser/net:crurl",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
+    "//ios/chrome/browser/ui/ntp:metrics",
     "//ios/chrome/common/ui/confirmation_alert",
     "//ios/chrome/common/ui/favicon",
     "//ios/chrome/common/ui/favicon:favicon_constants",
diff --git a/ios/chrome/browser/ui/follow/first_follow_coordinator.mm b/ios/chrome/browser/ui/follow/first_follow_coordinator.mm
index 8219c86..3ff9e7fc 100644
--- a/ios/chrome/browser/ui/follow/first_follow_coordinator.mm
+++ b/ios/chrome/browser/ui/follow/first_follow_coordinator.mm
@@ -4,6 +4,8 @@
 
 #import "ios/chrome/browser/ui/follow/first_follow_coordinator.h"
 
+#include "ios/chrome/browser/discover_feed/discover_feed_service.h"
+#include "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/main/browser.h"
@@ -13,6 +15,7 @@
 #import "ios/chrome/browser/ui/follow/first_follow_favicon_data_source.h"
 #import "ios/chrome/browser/ui/follow/first_follow_view_controller.h"
 #import "ios/chrome/browser/ui/follow/followed_web_channel.h"
+#import "ios/chrome/browser/ui/ntp/feed_metrics_recorder.h"
 #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h"
 #import "ios/chrome/common/ui/favicon/favicon_attributes.h"
 #import "ios/chrome/common/ui/favicon/favicon_constants.h"
@@ -36,6 +39,9 @@
 // The view controller is owned by the view hierarchy.
 @property(nonatomic, weak) FirstFollowViewController* firstFollowViewController;
 
+// Feed metrics recorder.
+@property(nonatomic, weak) FeedMetricsRecorder* feedMetricsRecorder;
+
 @end
 
 @implementation FirstFollowCoordinator
@@ -46,6 +52,9 @@
   FirstFollowViewController* firstFollowViewController =
       [[FirstFollowViewController alloc] init];
   firstFollowViewController.followedWebChannel = self.followedWebChannel;
+  self.feedMetricsRecorder = DiscoverFeedServiceFactory::GetForBrowserState(
+                                 self.browser->GetBrowserState())
+                                 ->GetFeedMetricsRecorder();
   // Ownership is passed to VC so this object is not retained after VC closes.
   self.followedWebChannel = nil;
   self.firstFollowViewController = firstFollowViewController;
@@ -73,9 +82,13 @@
         UIModalPresentationFormSheet;
   }
 
-  [self.baseViewController presentViewController:firstFollowViewController
-                                        animated:YES
-                                      completion:nil];
+  __weak __typeof(self) weakSelf = self;
+  [self.baseViewController
+      presentViewController:firstFollowViewController
+                   animated:YES
+                 completion:^() {
+                   [weakSelf.feedMetricsRecorder recordFirstFollowShown];
+                 }];
 }
 
 - (void)stop {
@@ -87,6 +100,7 @@
 #pragma mark - ConfirmationAlertActionHandler
 
 - (void)confirmationAlertPrimaryAction {
+  [self.feedMetricsRecorder recordFirstFollowTappedGoToFeed];
   if (self.firstFollowViewController.followedWebChannel.available) {
     [self.newTabPageCommandsHandler
         openNTPScrolledIntoFeedType:FeedTypeFollowing];
@@ -97,6 +111,7 @@
 }
 
 - (void)confirmationAlertSecondaryAction {
+  [self.feedMetricsRecorder recordFirstFollowTappedGotIt];
   if (self.baseViewController.presentedViewController) {
     [self.baseViewController dismissViewControllerAnimated:YES completion:nil];
   }
diff --git a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h
index acca893..f13ac4a 100644
--- a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h
+++ b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h
@@ -269,6 +269,15 @@
 // confirmation snackbar in the management UI.
 - (void)recordManagementTappedUnfollowTryAgainOnSnackbar;
 
+// Record metrics for when the first follow sheet is shown.
+- (void)recordFirstFollowShown;
+
+// Record metrics for when the user taps "Go To Feed" on the first follow sheet.
+- (void)recordFirstFollowTappedGoToFeed;
+
+// Record metrics for when the user taps "Got it" on the first follow sheet.
+- (void)recordFirstFollowTappedGotIt;
+
 // Delegate to get the currently selected feed.
 @property(nonatomic, weak) id<FeedControlDelegate> feedControlDelegate;
 
diff --git a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
index c49c52b6..97340f1 100644
--- a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
@@ -172,6 +172,12 @@
 const char kDiscoverFeedUserActionManagementTappedUnfollowTryAgainOnSnackbar[] =
     "ContentSuggestions.Feed.Management.TappedUnfollowTryAgainOnSnackbar";
 
+// User action names for first follow surface.
+const char kFirstFollowGoToFeedButtonTapped[] =
+    "ContentSuggestions.Follow.FirstFollow.GoToFeedButtonTapped";
+const char kFirstFollowGotItButtonTapped[] =
+    "ContentSuggestions.Follow.FirstFollow.GotItButtonTapped";
+
 // User action name for engaging with feed.
 const char kDiscoverFeedUserActionEngaged[] = "ContentSuggestions.Feed.Engaged";
 
@@ -795,6 +801,23 @@
       kDiscoverFeedUserActionManagementTappedUnfollowTryAgainOnSnackbar));
 }
 
+- (void)recordFirstFollowShown {
+  [self recordDiscoverFeedUserActionHistogram:FeedUserActionType::
+                                                  kFirstFollowSheetShown];
+}
+
+- (void)recordFirstFollowTappedGoToFeed {
+  [self recordDiscoverFeedUserActionHistogram:
+            FeedUserActionType::kFirstFollowSheetTappedGoToFeed];
+  base::RecordAction(base::UserMetricsAction(kFirstFollowGoToFeedButtonTapped));
+}
+
+- (void)recordFirstFollowTappedGotIt {
+  [self recordDiscoverFeedUserActionHistogram:FeedUserActionType::
+                                                  kFirstFollowSheetTappedGotIt];
+  base::RecordAction(base::UserMetricsAction(kFirstFollowGotItButtonTapped));
+}
+
 #pragma mark - Private
 
 // Returns the UserSettingsOnStart value based on the user settings.
diff --git a/ios/chrome/browser/ui/text_zoom/text_zoom_coordinator.mm b/ios/chrome/browser/ui/text_zoom/text_zoom_coordinator.mm
index 17d9554..9501e70 100644
--- a/ios/chrome/browser/ui/text_zoom/text_zoom_coordinator.mm
+++ b/ios/chrome/browser/ui/text_zoom/text_zoom_coordinator.mm
@@ -49,8 +49,7 @@
       initWithWebStateList:self.browser->GetWebStateList()
             commandHandler:self.textZoomCommandHandler];
 
-  self.textZoomViewController = [[TextZoomViewController alloc]
-      initWithDarkAppearance:self.browser->GetBrowserState()->IsOffTheRecord()];
+  self.textZoomViewController = [[TextZoomViewController alloc] init];
   self.textZoomViewController.commandHandler = self.textZoomCommandHandler;
 
   self.textZoomViewController.zoomHandler = self.mediator;
diff --git a/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h b/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h
index 5ff09bd7d..092fe43 100644
--- a/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h
+++ b/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h
@@ -25,10 +25,7 @@
 
 @interface TextZoomViewController : UIViewController <TextZoomConsumer>
 
-- (instancetype)initWithDarkAppearance:(BOOL)darkAppearance
-    NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
 - (instancetype)initWithNibName:(NSString*)nibNameOrNil
                          bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
 - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.mm b/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.mm
index 7fd9a99d..9d66712 100644
--- a/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.mm
+++ b/ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.mm
@@ -48,11 +48,8 @@
 
 @implementation TextZoomViewController
 
-- (instancetype)initWithDarkAppearance:(BOOL)darkAppearance {
-  if (self = [super initWithNibName:nil bundle:nil]) {
-    _darkAppearance = darkAppearance;
-  }
-  return self;
+- (instancetype)init {
+  return [super initWithNibName:nil bundle:nil];
 }
 
 #pragma mark - UIViewController
diff --git a/ios/chrome/browser/web/features.cc b/ios/chrome/browser/web/features.cc
index 61623ba..f59354f 100644
--- a/ios/chrome/browser/web/features.cc
+++ b/ios/chrome/browser/web/features.cc
@@ -12,6 +12,9 @@
 const base::Feature kWebPageAlternativeTextZoom{
     "WebPageAlternativeTextZoom", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kWebPageTextZoomIPad{"WebPageTextZoomIPad",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kRestoreSessionFromCache{"RestoreSessionFromCache",
                                              base::FEATURE_ENABLED_BY_DEFAULT};
 
diff --git a/ios/chrome/browser/web/features.h b/ios/chrome/browser/web/features.h
index 73a040c..e6ed29e 100644
--- a/ios/chrome/browser/web/features.h
+++ b/ios/chrome/browser/web/features.h
@@ -17,6 +17,9 @@
 // Used to enable a different method of zooming web pages.
 extern const base::Feature kWebPageAlternativeTextZoom;
 
+// Reneables text zoom on iPad.
+extern const base::Feature kWebPageTextZoomIPad;
+
 // Feature flag for to use native session restoration.
 extern const base::Feature kRestoreSessionFromCache;
 
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index b5fb9845..850eebdd 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -46,15 +46,17 @@
 }
 
 test("mojo_perftests") {
+  sources = [ "//mojo/core/handle_table_perftest.cc" ]
   deps = [
     "//mojo/core/test:run_all_perftests",
     "//mojo/core/test:test_support",
     "//mojo/public/c/system/tests:perftests",
     "//mojo/public/cpp/bindings/tests:perftests",
+    "//testing/perf",
   ]
 
   if (!is_ios) {
-    sources = [ "//mojo/core/message_pipe_perftest.cc" ]
+    sources += [ "//mojo/core/message_pipe_perftest.cc" ]
 
     deps += [
       "//base",
diff --git a/mojo/core/handle_table_perftest.cc b/mojo/core/handle_table_perftest.cc
new file mode 100644
index 0000000..0e870b57
--- /dev/null
+++ b/mojo/core/handle_table_perftest.cc
@@ -0,0 +1,155 @@
+// 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 "mojo/core/handle_table.h"
+
+#include "base/memory/raw_ptr.h"
+#include "base/synchronization/lock.h"
+#include "base/timer/lap_timer.h"
+#include "mojo/core/dispatcher.h"
+#include "mojo/public/c/system/types.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_result_reporter.h"
+
+namespace mojo::core {
+namespace {
+
+using ::base::LapTimer;
+using ::perf_test::PerfResultReporter;
+using ::testing::Eq;
+using ::testing::Gt;
+using ::testing::Ne;
+
+class FakeMessagePipeDispatcherForTesting : public Dispatcher {
+ public:
+  FakeMessagePipeDispatcherForTesting() = default;
+
+  FakeMessagePipeDispatcherForTesting(
+      const FakeMessagePipeDispatcherForTesting&) = delete;
+  FakeMessagePipeDispatcherForTesting& operator=(
+      const FakeMessagePipeDispatcherForTesting&) = delete;
+
+  Type GetType() const override { return Type::MESSAGE_PIPE; }
+  MojoResult Close() override { return MOJO_RESULT_OK; }
+
+ private:
+  ~FakeMessagePipeDispatcherForTesting() override = default;
+};
+
+// Returns the handles of the dispatchers added.
+std::vector<MojoHandle> AddDispatchersForTesting(
+    const int num_dispatchers_to_add,
+    HandleTable* handle_table) {
+  std::vector<MojoHandle> handles;
+  handles.reserve(num_dispatchers_to_add);
+  scoped_refptr<Dispatcher> dispatcher(new FakeMessagePipeDispatcherForTesting);
+  const base::AutoLock auto_lock(handle_table->GetLock());
+  for (int i = 0; i < num_dispatchers_to_add; ++i) {
+    const MojoHandle handle = handle_table->AddDispatcher(dispatcher);
+    EXPECT_THAT(handle, Ne(MOJO_HANDLE_INVALID));
+    handles.push_back(handle);
+  }
+  return handles;
+}
+
+constexpr char kMetricThroughput[] = "Throughput";
+
+PerfResultReporter MakeReporter(const std::string& story_name) {
+  PerfResultReporter reporter("HandleTable", story_name);
+  reporter.RegisterImportantMetric(kMetricThroughput, "runs/s");
+  return reporter;
+}
+
+}  // namespace
+
+TEST(HandleTablePerfTest, GetDispatcherDifferentHandles) {
+  // The number below is based on https://crbug.com/1295449#c2.
+  constexpr int kNumDispatchers = 10000;
+  HandleTable handle_table;
+  const std::vector<MojoHandle> handles =
+      AddDispatchersForTesting(kNumDispatchers, &handle_table);
+  ASSERT_THAT(handles.size(), Gt(0ul));
+  const int handles_last_index = handles.size() - 1;
+
+  int current_index = 0;
+  LapTimer timer;
+  // Query for dispatchers in a round-robin manner until the time limit expires.
+  while (!timer.HasTimeLimitExpired()) {
+    handle_table.GetDispatcher(handles[current_index]);
+    current_index = current_index == handles_last_index ? 0 : current_index + 1;
+    timer.NextLap();
+  }
+
+  PerfResultReporter reporter = MakeReporter("GetDispatcherDifferentHandles");
+  reporter.AddResult(kMetricThroughput, timer.LapsPerSecond());
+}
+
+TEST(HandleTablePerfTest, GetDispatcherSameHandle) {
+  // The number below is based on https://crbug.com/1295449#c2.
+  constexpr int kNumDispatchers = 10000;
+  HandleTable handle_table;
+  const std::vector<MojoHandle> handles =
+      AddDispatchersForTesting(kNumDispatchers, &handle_table);
+  ASSERT_THAT(handles.size(), Gt(0ul));
+
+  LapTimer timer;
+  while (!timer.HasTimeLimitExpired()) {
+    handle_table.GetDispatcher(handles[0]);
+    timer.NextLap();
+  }
+
+  PerfResultReporter reporter = MakeReporter("GetDispatcherSameHandle");
+  reporter.AddResult(kMetricThroughput, timer.LapsPerSecond());
+}
+
+TEST(HandleTablePerfTest, GetDispatcherMixedHandles) {
+  // The number below is based on https://crbug.com/1295449#c2.
+  constexpr int kNumDispatchers = 10000;
+  HandleTable handle_table;
+  const std::vector<MojoHandle> handles =
+      AddDispatchersForTesting(kNumDispatchers, &handle_table);
+  ASSERT_THAT(handles.size(), Gt(0ul));
+  const int handles_last_index = handles.size() - 1;
+
+  int current_index = 0;
+  LapTimer timer;
+  while (!timer.HasTimeLimitExpired()) {
+    // Sample each index 3 times, thus sampling the same index as the previous
+    // one roughly 66% of the time. Based on https://crbug.com/1295449.
+    handle_table.GetDispatcher(handles[current_index / 4]);
+    current_index = current_index == handles_last_index ? 0 : current_index + 1;
+    timer.NextLap();
+  }
+
+  PerfResultReporter reporter = MakeReporter("GetDispatcherMixedHandles");
+  reporter.AddResult(kMetricThroughput, timer.LapsPerSecond());
+}
+
+TEST(HandleTablePerfTest, AddAndRemoveDispatcher) {
+  // The number below is based on https://crbug.com/1295449#c2.
+  constexpr int kNumDispatchers = 10000;
+  HandleTable handle_table;
+  const std::vector<MojoHandle> handles =
+      AddDispatchersForTesting(kNumDispatchers, &handle_table);
+  ASSERT_THAT(handles.size(), Gt(0ul));
+
+  LapTimer timer;
+  while (!timer.HasTimeLimitExpired()) {
+    const base::AutoLock auto_lock(handle_table.GetLock());
+    scoped_refptr<Dispatcher> dispatcher(
+        new FakeMessagePipeDispatcherForTesting);
+    const MojoHandle handle = handle_table.AddDispatcher(std::move(dispatcher));
+    EXPECT_THAT(handle, Ne(MOJO_HANDLE_INVALID));
+    const MojoResult result =
+        handle_table.GetAndRemoveDispatcher(handle, &dispatcher);
+    EXPECT_THAT(result, Eq(MOJO_RESULT_OK));
+    timer.NextLap();
+  }
+
+  PerfResultReporter reporter = MakeReporter("AddAndRemoveDispatcher");
+  reporter.AddResult(kMetricThroughput, timer.LapsPerSecond());
+}
+
+}  // namespace mojo::core
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc
index e9bf047..6308d31 100644
--- a/pdf/pdf_view_plugin_base.cc
+++ b/pdf/pdf_view_plugin_base.cc
@@ -17,7 +17,6 @@
 #include "base/callback.h"
 #include "base/check.h"
 #include "base/check_op.h"
-#include "base/containers/contains.h"
 #include "base/containers/fixed_flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/containers/span.h"
@@ -359,21 +358,6 @@
   paint_manager_.InvalidateRect(gfx::Rect(plugin_rect_.size()));
 }
 
-void PdfViewPluginBase::DocumentHasUnsupportedFeature(
-    const std::string& feature) {
-  DCHECK(!feature.empty());
-  const std::string metric = "PDF_Unsupported_" + feature;
-  bool inserted = unsupported_features_reported_.insert(metric).second;
-  if (inserted)
-    UserMetricsRecordAction(metric);
-
-  if (!full_frame() || notified_browser_about_unsupported_feature_)
-    return;
-
-  NotifyUnsupportedFeature();
-  notified_browser_about_unsupported_feature_ = true;
-}
-
 void PdfViewPluginBase::DocumentLoadProgress(uint32_t available,
                                              uint32_t doc_size) {
   double progress = 0.0;
@@ -602,11 +586,6 @@
   return doc_info;
 }
 
-bool PdfViewPluginBase::UnsupportedFeatureIsReportedForTesting(
-    const std::string& feature) const {
-  return base::Contains(unsupported_features_reported_, feature);
-}
-
 void PdfViewPluginBase::InitializeEngineForTesting(
     std::unique_ptr<PDFiumEngine> engine) {
   DCHECK(engine);
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h
index 8005e3a..2454e2f 100644
--- a/pdf/pdf_view_plugin_base.h
+++ b/pdf/pdf_view_plugin_base.h
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/containers/flat_set.h"
 #include "base/containers/queue.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/weak_ptr.h"
@@ -112,7 +111,6 @@
   void Print() override;
   void DocumentLoadComplete() override;
   void DocumentLoadFailed() override;
-  void DocumentHasUnsupportedFeature(const std::string& feature) override;
   void DocumentLoadProgress(uint32_t available, uint32_t doc_size) override;
   void FormFieldFocusChange(PDFEngine::FocusFieldType type) override;
   void SetIsSelecting(bool is_selecting) override;
@@ -141,12 +139,6 @@
   // Gets the accessibility doc info based on the information from `engine_`.
   AccessibilityDocInfo GetAccessibilityDocInfo() const;
 
-  bool UnsupportedFeatureIsReportedForTesting(const std::string& feature) const;
-
-  bool GetNotifiedBrowserAboutUnsupportedFeatureForTesting() const {
-    return notified_browser_about_unsupported_feature_;
-  }
-
   void InitializeEngineForTesting(std::unique_ptr<PDFiumEngine> engine);
 
   void set_full_frame_for_testing(bool full_frame) { full_frame_ = full_frame; }
@@ -320,10 +312,6 @@
                                       const gfx::PointF& right,
                                       int right_height) = 0;
 
-  // Notifies the user about unsupported feature if the PDF Viewer occupies the
-  // full frame.
-  virtual void NotifyUnsupportedFeature() = 0;
-
   // Records user actions.
   virtual void UserMetricsRecordAction(const std::string& action) = 0;
 
@@ -527,14 +515,6 @@
   // reconstructing the tree for new document layouts.
   int32_t next_accessibility_page_index_ = 0;
 
-  // Keeps track of which unsupported features have been reported to avoid
-  // spamming the metrics if a feature shows up many times per document.
-  base::flat_set<std::string> unsupported_features_reported_;
-
-  // Indicates whether the browser has been notified about an unsupported
-  // feature once, which helps prevent the infobar from going up more than once.
-  bool notified_browser_about_unsupported_feature_ = false;
-
   // Assigned a value only between `PrintBegin()` and `PrintEnd()` calls.
   absl::optional<blink::WebPrintParams> print_params_;
 
diff --git a/pdf/pdf_view_plugin_base_unittest.cc b/pdf/pdf_view_plugin_base_unittest.cc
index 274a99c..5320e635 100644
--- a/pdf/pdf_view_plugin_base_unittest.cc
+++ b/pdf/pdf_view_plugin_base_unittest.cc
@@ -152,8 +152,6 @@
               (const gfx::PointF&, int, const gfx::PointF&, int),
               (override));
 
-  MOCK_METHOD(void, NotifyUnsupportedFeature, (), (override));
-
   MOCK_METHOD(void, UserMetricsRecordAction, (const std::string&), (override));
 
   void clear_sent_messages() { sent_messages_.clear(); }
@@ -346,66 +344,6 @@
             fake_plugin_.sent_messages()[0]);
 }
 
-TEST_F(PdfViewPluginBaseTest, DocumentHasUnsupportedFeatureInFullFrame) {
-  fake_plugin_.set_full_frame_for_testing(true);
-  ASSERT_TRUE(fake_plugin_.full_frame());
-
-  // Arbitrary feature names and their matching metric names.
-  static constexpr char kFeature1[] = "feature1";
-  static constexpr char kMetric1[] = "PDF_Unsupported_feature1";
-  static constexpr char kFeature2[] = "feature2";
-  static constexpr char kMetric2[] = "PDF_Unsupported_feature2";
-
-  // Find unsupported `kFeature1` for the first time.
-  EXPECT_FALSE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric1));
-  EXPECT_FALSE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-  EXPECT_CALL(fake_plugin_, NotifyUnsupportedFeature());
-  EXPECT_CALL(fake_plugin_, UserMetricsRecordAction(kMetric1));
-
-  fake_plugin_.DocumentHasUnsupportedFeature(kFeature1);
-  EXPECT_TRUE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric1));
-  EXPECT_TRUE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-
-  // Find unsupported `kFeature2` for the first time.
-  EXPECT_FALSE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric2));
-  EXPECT_CALL(fake_plugin_, UserMetricsRecordAction(kMetric2));
-
-  fake_plugin_.DocumentHasUnsupportedFeature(kFeature2);
-  EXPECT_TRUE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric2));
-  EXPECT_TRUE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-
-  // Find unsupported `kFeature1` for the second time.
-  fake_plugin_.DocumentHasUnsupportedFeature(kFeature1);
-  EXPECT_TRUE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric1));
-  EXPECT_TRUE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-}
-
-TEST_F(PdfViewPluginBaseTest, DocumentHasUnsupportedFeatureWithoutFullFrame) {
-  ASSERT_FALSE(fake_plugin_.full_frame());
-
-  // An arbitrary feature name and its matching metric name.
-  static constexpr char kFeature[] = "feature";
-  static constexpr char kMetric[] = "PDF_Unsupported_feature";
-
-  EXPECT_FALSE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric));
-  EXPECT_FALSE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-
-  // NotifyUnsupportedFeature() should never be called if the viewer doesn't
-  // occupy the whole frame, but the metrics should still be recorded.
-  EXPECT_CALL(fake_plugin_, NotifyUnsupportedFeature()).Times(0);
-  EXPECT_CALL(fake_plugin_, UserMetricsRecordAction(kMetric));
-
-  fake_plugin_.DocumentHasUnsupportedFeature(kFeature);
-  EXPECT_TRUE(fake_plugin_.UnsupportedFeatureIsReportedForTesting(kMetric));
-  EXPECT_FALSE(
-      fake_plugin_.GetNotifiedBrowserAboutUnsupportedFeatureForTesting());
-}
-
 TEST_F(PdfViewPluginBaseWithEngineTest, HandleInputEvent) {
   auto* engine = static_cast<TestPDFiumEngine*>(fake_plugin_.engine());
   EXPECT_CALL(*engine, HandleInputEvent)
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
index 9a0661b..c1ec327 100644
--- a/pdf/pdf_view_web_plugin.cc
+++ b/pdf/pdf_view_web_plugin.cc
@@ -24,6 +24,7 @@
 #include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "base/thread_annotations.h"
 #include "base/threading/sequenced_task_runner_handle.h"
@@ -744,6 +745,20 @@
   return results;
 }
 
+void PdfViewWebPlugin::DocumentHasUnsupportedFeature(
+    const std::string& feature) {
+  DCHECK(!feature.empty());
+  std::string metric = base::StrCat({"PDF_Unsupported_", feature});
+  if (unsupported_features_reported_.insert(metric).second)
+    client_->RecordComputedAction(metric);
+
+  if (!full_frame() || notified_browser_about_unsupported_feature_)
+    return;
+
+  notified_browser_about_unsupported_feature_ = true;
+  pdf_service_->HasUnsupportedFeature();
+}
+
 bool PdfViewWebPlugin::IsPrintPreview() const {
   return is_print_preview_;
 }
@@ -1040,11 +1055,7 @@
   pdf_service_->SelectionChanged(left, left_height, right, right_height);
 }
 
-void PdfViewWebPlugin::NotifyUnsupportedFeature() {
-  DCHECK(full_frame());
-  pdf_service_->HasUnsupportedFeature();
-}
-
+// TODO(crbug.com/1302059): Delete after merging with `PdfViewPluginBase`.
 void PdfViewWebPlugin::UserMetricsRecordAction(const std::string& action) {
   client_->RecordComputedAction(action);
 }
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h
index b5030eae..aae60a25 100644
--- a/pdf/pdf_view_web_plugin.h
+++ b/pdf/pdf_view_web_plugin.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
@@ -275,6 +276,7 @@
   std::vector<SearchStringResult> SearchString(const char16_t* string,
                                                const char16_t* term,
                                                bool case_sensitive) override;
+  void DocumentHasUnsupportedFeature(const std::string& feature) override;
   bool IsPrintPreview() const override;
   SkColor GetBackgroundColor() const override;
   void CaretChanged(const gfx::Rect& caret_rect) override;
@@ -344,7 +346,6 @@
                               int left_height,
                               const gfx::PointF& right,
                               int right_height) override;
-  void NotifyUnsupportedFeature() override;
   void UserMetricsRecordAction(const std::string& action) override;
   gfx::Vector2d plugin_offset_in_frame() const override;
 
@@ -501,6 +502,14 @@
   // Only instantiated when not print previewing.
   std::unique_ptr<MetricsHandler> metrics_handler_;
 
+  // Keeps track of which unsupported features have been reported to avoid
+  // spamming the metrics if a feature shows up many times per document.
+  base::flat_set<std::string> unsupported_features_reported_;
+
+  // Indicates whether the browser has been notified about an unsupported
+  // feature once, which helps prevent the infobar from going up more than once.
+  bool notified_browser_about_unsupported_feature_ = false;
+
   // The metafile in which to save the printed output. Assigned a value only
   // between `PrintBegin()` and `PrintEnd()` calls.
   raw_ptr<printing::MetafileSkia> printing_metafile_ = nullptr;
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc
index e1932056..a2fea25 100644
--- a/pdf/pdf_view_web_plugin_unittest.cc
+++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -625,6 +625,63 @@
             plugin_->document_load_state_for_testing());
 }
 
+TEST_F(PdfViewWebPluginTest, DocumentHasUnsupportedFeature) {
+  EXPECT_CALL(*client_ptr_, RecordComputedAction).Times(AnyNumber());
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature1"));
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature2"));
+
+  // `HasUnsupportedFeature()` is not called if the viewer is not full-frame.
+  EXPECT_CALL(pdf_service_, HasUnsupportedFeature).Times(0);
+
+  plugin_->DocumentHasUnsupportedFeature("feature1");
+  plugin_->DocumentHasUnsupportedFeature("feature2");
+
+  pdf_receiver_.FlushForTesting();
+}
+
+TEST_F(PdfViewWebPluginTest, DocumentHasUnsupportedFeatureWithRepeatedFeature) {
+  // Metrics should only be recorded once per feature.
+  EXPECT_CALL(*client_ptr_, RecordComputedAction).Times(AnyNumber());
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature"));
+
+  // `HasUnsupportedFeature()` is not called if the viewer is not full-frame.
+  EXPECT_CALL(pdf_service_, HasUnsupportedFeature).Times(0);
+
+  plugin_->DocumentHasUnsupportedFeature("feature");
+  plugin_->DocumentHasUnsupportedFeature("feature");
+
+  pdf_receiver_.FlushForTesting();
+}
+
+TEST_F(PdfViewWebPluginFullFrameTest, DocumentHasUnsupportedFeature) {
+  EXPECT_CALL(*client_ptr_, RecordComputedAction).Times(AnyNumber());
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature1"));
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature2"));
+
+  // `HasUnsupportedFeature()` is called once for all features.
+  EXPECT_CALL(pdf_service_, HasUnsupportedFeature);
+
+  plugin_->DocumentHasUnsupportedFeature("feature1");
+  plugin_->DocumentHasUnsupportedFeature("feature2");
+
+  pdf_receiver_.FlushForTesting();
+}
+
+TEST_F(PdfViewWebPluginFullFrameTest,
+       DocumentHasUnsupportedFeatureWithRepeatedFeature) {
+  // Metrics should only be recorded once per feature.
+  EXPECT_CALL(*client_ptr_, RecordComputedAction).Times(AnyNumber());
+  EXPECT_CALL(*client_ptr_, RecordComputedAction("PDF_Unsupported_feature"));
+
+  // `HasUnsupportedFeature()` is called once for all features.
+  EXPECT_CALL(pdf_service_, HasUnsupportedFeature);
+
+  plugin_->DocumentHasUnsupportedFeature("feature");
+  plugin_->DocumentHasUnsupportedFeature("feature");
+
+  pdf_receiver_.FlushForTesting();
+}
+
 TEST_F(PdfViewWebPluginTest, UpdateGeometrySetsPluginRect) {
   EXPECT_CALL(*engine_ptr_, ZoomUpdated(2.0f));
   TestUpdateGeometrySetsPluginRect(
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index afe609f..f5d6369 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -8240,15 +8240,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8274,7 +8274,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8750,15 +8750,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M102/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8784,7 +8784,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 4e9070e..a5cd3d759 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -46214,15 +46214,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46248,7 +46248,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46724,15 +46724,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M102/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46758,7 +46758,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47238,15 +47238,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47272,7 +47272,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47748,15 +47748,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M102/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47782,7 +47782,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48330,15 +48330,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48364,7 +48364,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48840,15 +48840,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M102/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48874,7 +48874,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49422,15 +49422,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49456,7 +49456,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49932,15 +49932,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M102/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49966,7 +49966,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.97"
+              "revision": "version:102.0.5005.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 8791eca..277112f 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -426,16 +426,16 @@
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M102/out/Release',
-      '--impl-version=102'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=102',
     ],
     'identifier': 'with_impl_from_102',
     'swarming': {
@@ -443,10 +443,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.97'
+          'revision': 'version:102.0.5005.98',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -570,16 +570,16 @@
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M102/out/Release',
-      '--impl-version=102'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=102',
     ],
     'identifier': 'with_impl_from_102',
     'swarming': {
@@ -587,10 +587,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.97'
+          'revision': 'version:102.0.5005.98',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -714,16 +714,16 @@
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M102/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M102/out/Release',
-      '--client-version=102'
+      '--client-version=102',
     ],
     'identifier': 'with_client_from_102',
     'swarming': {
@@ -731,10 +731,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.97'
+          'revision': 'version:102.0.5005.98',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
diff --git a/testing/scripts/common.py b/testing/scripts/common.py
index c25219b7..0ffbca0 100644
--- a/testing/scripts/common.py
+++ b/testing/scripts/common.py
@@ -210,7 +210,7 @@
   def convert_trie_to_flat_paths(trie, prefix=None):
     # Also see blinkpy.web_tests.layout_package.json_results_generator
     result = {}
-    for name, data in trie.iteritems():
+    for name, data in trie.items():
       if prefix:
         name = prefix + test_separator + name
       if len(data) and not 'actual' in data and not 'expected' in data:
@@ -293,7 +293,7 @@
   mapping = {}
 
   for cur_iteration_data in output.get('per_iteration_data', []):
-    for test_fullname, results in cur_iteration_data.iteritems():
+    for test_fullname, results in cur_iteration_data.items():
       # Results is a list with one entry per test try. Last one is the final
       # result.
       last_result = results[-1]
diff --git a/testing/scripts/metrics_python_tests.py b/testing/scripts/metrics_python_tests.py
index 2746430..2cd7cec 100755
--- a/testing/scripts/metrics_python_tests.py
+++ b/testing/scripts/metrics_python_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env vpython3
 # 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.
@@ -17,7 +17,7 @@
 
 def main_run(args):
   with common.temporary_file() as tempfile_path:
-    rc = common.run_command(['vpython',
+    rc = common.run_command(['vpython3',
         os.path.join(common.SRC_DIR, 'testing', 'test_env.py'),
         os.path.join(common.SRC_DIR, 'tools', 'metrics',
                      'metrics_python_tests.py'),
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 033d3a5..90164ba8 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2177,6 +2177,26 @@
             ]
         }
     ],
+    "CheckCacheForQueuedRequests": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_100",
+                    "enable_features": [
+                        "CheckCacheForQueuedRequests"
+                    ]
+                }
+            ]
+        }
+    ],
     "ChromeCleanupDistribution": [
         {
             "platforms": [
@@ -5752,17 +5772,17 @@
             ]
         }
     ],
-    "OmniboxDisableHistoryQuickProviderCacheFileMobile": [
+    "OmniboxDisableHistoryQuickProviderCacheFileiOS": [
         {
             "platforms": [
-                "android",
                 "ios"
             ],
             "experiments": [
                 {
-                    "name": "Enabled_MaxIndex200",
+                    "name": "Enabled_MaxIndex400",
                     "params": {
-                        "MaxNumHQPUrlsIndexedAtStartupOnNonLowEndDevices": "200"
+                        "MaxNumHQPUrlsIndexedAtStartupOnLowEndDevices": "100",
+                        "MaxNumHQPUrlsIndexedAtStartupOnNonLowEndDevices": "400"
                     },
                     "enable_features": [
                         "OmniboxHistoryQuickProviderAblateInMemoryURLIndexCacheFile"
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index dd4dcf6..d0235aa 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -719,7 +719,7 @@
 // TODO(crbug.com/920069): Remove this once the feature has
 // landed and no compat issues are reported.
 const base::Feature kOffsetParentNewSpecBehavior{
-    "OffsetParentNewSpecBehavior", base::FEATURE_ENABLED_BY_DEFAULT};
+    "OffsetParentNewSpecBehavior", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Makes form elements cancel previous form submissions made by the same form
 // when the default event handler schedules a form submission.
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index ac70756..8f852e8 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -139,8 +139,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_layout_constraints_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_set_element_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_set_element_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 173262db..938b099 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -227,8 +227,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event_init.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index 430319f6..24f8138c 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -117,7 +117,6 @@
           "//third_party/blink/renderer/core/css/css_try_rule.idl",
           "//third_party/blink/renderer/core/document_transition/document_transition.idl",
           "//third_party/blink/renderer/core/document_transition/document_transition_callback.idl",
-          "//third_party/blink/renderer/core/document_transition/document_transition_set_element_options.idl",
           "//third_party/blink/renderer/core/document_transition/document_transition_supplement.idl",
           "//third_party/blink/renderer/core/dom/abort_controller.idl",
           "//third_party/blink/renderer/core/dom/abort_signal.idl",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index 04e3181..66e0217 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -107,7 +107,6 @@
           "//third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
           "//third_party/blink/renderer/modules/clipboard/clipboard.idl",
           "//third_party/blink/renderer/modules/clipboard/clipboard_item.idl",
-          "//third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl",
           "//third_party/blink/renderer/modules/clipboard/navigator_clipboard.idl",
           "//third_party/blink/renderer/modules/compression/compression_stream.idl",
           "//third_party/blink/renderer/modules/compression/decompression_stream.idl",
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.cc b/third_party/blink/renderer/core/document_transition/document_transition.cc
index 067be55..516e063 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition.cc
@@ -13,7 +13,6 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_set_element_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -118,24 +117,6 @@
   return true;
 }
 
-void DocumentTransition::setElement(
-    ScriptState* script_state,
-    Element* element,
-    const AtomicString& tag,
-    const DocumentTransitionSetElementOptions* opts,
-    ExceptionState& exception_state) {
-  if (!style_tracker_) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
-                                      "Transition is aborted.");
-    return;
-  }
-
-  if (tag.IsNull())
-    style_tracker_->RemoveSharedElement(element);
-  else
-    style_tracker_->AddSharedElement(element, tag);
-}
-
 ScriptPromise DocumentTransition::start(ScriptState* script_state,
                                         ExceptionState& exception_state) {
   return start(script_state, nullptr, exception_state);
@@ -209,9 +190,6 @@
   return start_promise_resolver_->Promise();
 }
 
-void DocumentTransition::ignoreCSSTaggedElements(ScriptState*,
-                                                 ExceptionState&) {}
-
 void DocumentTransition::abandon(ScriptState*, ExceptionState&) {
   CancelPendingTransition(kAbortedFromScript);
 }
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.h b/third_party/blink/renderer/core/document_transition/document_transition.h
index fffb50a710..ab4dd2d 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition.h
+++ b/third_party/blink/renderer/core/document_transition/document_transition.h
@@ -28,7 +28,6 @@
 namespace blink {
 
 class Document;
-class DocumentTransitionSetElementOptions;
 class Element;
 class ExceptionState;
 class LayoutObject;
@@ -61,17 +60,10 @@
   // can be started.
   bool StartNewTransition();
 
-  // JavaScript API implementation.
-  void setElement(ScriptState*,
-                  Element*,
-                  const AtomicString&,
-                  const DocumentTransitionSetElementOptions*,
-                  ExceptionState&);
   ScriptPromise start(ScriptState*, ExceptionState&);
   ScriptPromise start(ScriptState*,
                       V8DocumentTransitionCallback* callback,
                       ExceptionState&);
-  void ignoreCSSTaggedElements(ScriptState*, ExceptionState&);
   void abandon(ScriptState*, ExceptionState&);
 
   // This uses std::move semantics to take the request from this object.
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.idl b/third_party/blink/renderer/core/document_transition/document_transition.idl
index 90d2a58..e95f70f6 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition.idl
+++ b/third_party/blink/renderer/core/document_transition/document_transition.idl
@@ -9,10 +9,6 @@
     Exposed=Window,
     RuntimeEnabled=DocumentTransition
 ] interface DocumentTransition {
-  // Set or unset (if tag is null) an element that will participate in the next
-  // transition, whether as a part of captureAndHold or start phases.
-  [CallWith=ScriptState, RaisesException] void setElement(Element element, DOMString? tag, optional DocumentTransitionSetElementOptions options = {});
-
   // Starts the transition with the captured elements.
   // |callback| is used to asynchronously initialize the new DOM for the
   // transition. Animations are started when this callback returns.
@@ -20,9 +16,6 @@
   // are finished.
   [CallWith=ScriptState, RaisesException] Promise<void> start(optional DocumentTransitionCallback callback);
 
-  // Ignores CSS tagged elements
-  [CallWith=ScriptState, RaisesException] void ignoreCSSTaggedElements();
-
   // Abandons the transition.
   [CallWith=ScriptState, RaisesException] void abandon();
 };
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_set_element_options.idl b/third_party/blink/renderer/core/document_transition/document_transition_set_element_options.idl
deleted file mode 100644
index 8c7837a..0000000
--- a/third_party/blink/renderer/core/document_transition/document_transition_set_element_options.idl
+++ /dev/null
@@ -1,6 +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.
-
-dictionary DocumentTransitionSetElementOptions {
-};
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
index 948ee3bd..995d24c 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition_test.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
@@ -14,7 +14,6 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_callback.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_set_element_options.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/document_transition/document_transition_supplement.h"
@@ -267,6 +266,8 @@
   SetHtmlInnerHTML(R"HTML(
     <style>
       div { width: 100px; height: 100px; contain: paint }
+      #e1 { page-transition-tag: e1; }
+      #e3 { page-transition-tag: e3; }
     </style>
 
     <div id=e1></div>
@@ -294,8 +295,6 @@
   EXPECT_FALSE(ShouldCompositeForDocumentTransition(e2));
   EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
 
-  transition->setElement(script_state, e1, "e1", nullptr, exception_state);
-  transition->setElement(script_state, e3, "e3", nullptr, exception_state);
   transition->start(script_state, document_transition_callback,
                     exception_state);
 
@@ -328,9 +327,9 @@
 TEST_P(DocumentTransitionTest, UncontainedElementsAreCleared) {
   SetHtmlInnerHTML(R"HTML(
     <style>#e1 { width: 100px; height: 100px; contain: paint }</style>
-    <div id=e1></div>
-    <div id=e2></div>
-    <div id=e3></div>
+    <div id=e1 style="page-transition-tag: e1"></div>
+    <div id=e2 style="page-transition-tag: e2"></div>
+    <div id=e3 style="page-transition-tag: e3"></div>
   )HTML");
 
   auto* e1 = GetDocument().getElementById("e1");
@@ -353,24 +352,16 @@
   EXPECT_FALSE(ShouldCompositeForDocumentTransition(e2));
   EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
 
-  transition->setElement(script_state, e1, "e1", nullptr, exception_state);
-  transition->setElement(script_state, e2, "e2", nullptr, exception_state);
-  transition->setElement(script_state, e3, "e3", nullptr, exception_state);
   transition->start(script_state, document_transition_callback,
                     exception_state);
 
   EXPECT_TRUE(ShouldCompositeForDocumentTransition(e1));
-  EXPECT_TRUE(ShouldCompositeForDocumentTransition(e2));
-  EXPECT_TRUE(ShouldCompositeForDocumentTransition(e3));
+  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e2));
+  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
 
   // Update the lifecycle while keeping the transition active.
   UpdateAllLifecyclePhasesForTest();
 
-  // Since only the first element is contained, the rest should be cleared.
-  EXPECT_TRUE(ShouldCompositeForDocumentTransition(e1));
-  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e2));
-  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
-
   EXPECT_TRUE(ElementIsComposited("e1"));
   EXPECT_FALSE(ElementIsComposited("e2"));
   EXPECT_FALSE(ElementIsComposited("e3"));
@@ -378,6 +369,9 @@
 
 TEST_P(DocumentTransitionTest, StartSharedElementsWantToBeComposited) {
   SetHtmlInnerHTML(R"HTML(
+    <style>
+      div { contain: paint; width: 100px; height: 100px; background: blue; }
+    </style>
     <div id=e1></div>
     <div id=e2></div>
     <div id=e3></div>
@@ -396,43 +390,48 @@
   ExceptionState& exception_state = v8_scope.GetExceptionState();
 
   // Set two of the elements to be shared.
-  transition->setElement(script_state, e1, "e1", nullptr, exception_state);
-  transition->setElement(script_state, e3, "e3", nullptr, exception_state);
+  e1->setAttribute(html_names::kStyleAttr, "page-transition-tag: e1");
+  e3->setAttribute(html_names::kStyleAttr, "page-transition-tag: e3");
 
   struct Data {
     STACK_ALLOCATED();
 
    public:
-    Data(DocumentTransition* transition,
+    Data(Document& document,
+         DocumentTransition* transition,
          ScriptState* script_state,
          ExceptionState& exception_state,
          Element* e1,
          Element* e2)
-        : transition(transition),
+        : document(document),
+          transition(transition),
           script_state(script_state),
           exception_state(exception_state),
           e1(e1),
           e2(e2) {}
 
+    Document& document;
     DocumentTransition* transition;
     ScriptState* script_state;
     ExceptionState& exception_state;
     Element* e1;
     Element* e2;
   };
-  Data data(transition, script_state, exception_state, e1, e2);
+  Data data(GetDocument(), transition, script_state, exception_state, e1, e2);
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {
         auto* data =
             static_cast<Data*>(info.Data().As<v8::External>()->Value());
-
-        // Set two different elements as shared.
-        data->transition->setElement(data->script_state, data->e1, "e1",
-                                     nullptr, data->exception_state);
-        data->transition->setElement(data->script_state, data->e2, "e2",
-                                     nullptr, data->exception_state);
+        data->document.getElementById("e1")->setAttribute(
+            html_names::kStyleAttr, "");
+        data->document.getElementById("e3")->setAttribute(
+            html_names::kStyleAttr, "");
+        data->e1->setAttribute(html_names::kStyleAttr,
+                               "page-transition-tag: e1");
+        data->e2->setAttribute(html_names::kStyleAttr,
+                               "page-transition-tag: e2");
       };
   auto start_setup_callback =
       v8::Function::New(v8_scope.GetContext(), start_setup_lambda,
@@ -453,12 +452,6 @@
   EXPECT_TRUE(ShouldCompositeForDocumentTransition(e1));
   EXPECT_TRUE(ShouldCompositeForDocumentTransition(e2));
   EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
-
-  UpdateAllLifecyclePhasesAndFinishDirectives();
-
-  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e1));
-  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e2));
-  EXPECT_FALSE(ShouldCompositeForDocumentTransition(e3));
 }
 
 TEST_P(DocumentTransitionTest, AdditionalStartAfterStartAbortsTransition) {
@@ -642,18 +635,14 @@
 TEST_P(DocumentTransitionTest, DocumentTransitionPseudoTree) {
   SetHtmlInnerHTML(R"HTML(
     <style>
-      div { width: 100px; height: 100px; contain: paint }
+      div { width: 100px; height: 100px; contain: paint; background: blue }
     </style>
 
-    <div id=e1></div>
-    <div id=e2></div>
-    <div id=e3></div>
+    <div id=e1 style="page-transition-tag: e1"></div>
+    <div id=e2 style="page-transition-tag: e2"></div>
+    <div id=e3 style="page-transition-tag: e3"></div>
   )HTML");
 
-  auto* e1 = GetDocument().getElementById("e1");
-  auto* e2 = GetDocument().getElementById("e2");
-  auto* e3 = GetDocument().getElementById("e3");
-
   auto* transition =
       DocumentTransitionSupplement::EnsureDocumentTransition(GetDocument());
   ASSERT_TRUE(transition->StartNewTransition());
@@ -662,10 +651,6 @@
   ScriptState* script_state = v8_scope.GetScriptState();
   ExceptionState& exception_state = v8_scope.GetExceptionState();
 
-  transition->setElement(script_state, e1, "e1", nullptr, exception_state);
-  transition->setElement(script_state, e2, "e2", nullptr, exception_state);
-  transition->setElement(script_state, e3, "e3", nullptr, exception_state);
-
   struct Data {
     STACK_ALLOCATED();
 
@@ -688,21 +673,7 @@
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_lambda =
-      [](const v8::FunctionCallbackInfo<v8::Value>& info) {
-        auto* data =
-            static_cast<Data*>(info.Data().As<v8::External>()->Value());
-
-        auto* e1 = data->document.getElementById("e1");
-        auto* e2 = data->document.getElementById("e2");
-        auto* e3 = data->document.getElementById("e3");
-
-        data->transition->setElement(data->script_state, e1, "e1", nullptr,
-                                     data->exception_state);
-        data->transition->setElement(data->script_state, e2, "e2", nullptr,
-                                     data->exception_state);
-        data->transition->setElement(data->script_state, e3, "e3", nullptr,
-                                     data->exception_state);
-      };
+      [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
   auto start_setup_callback =
       v8::Function::New(v8_scope.GetContext(), start_setup_lambda,
                         v8::External::New(v8_scope.GetIsolate(), &data))
@@ -726,9 +697,9 @@
       div { width: 200px; height: 200px; contain: paint }
     </style>
 
-    <div id=e1></div>
-    <div id=e2></div>
-    <div id=e3></div>
+    <div id=e1 style="page-transition-tag: e1"></div>
+    <div id=e2 style="page-transition-tag: e2"></div>
+    <div id=e3 style="page-transition-tag: e3"></div>
   )HTML");
   test::RunPendingTasks();
   EXPECT_EQ(GetState(transition), State::kStarted);
diff --git a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.cc b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.cc
index 4867af9..c10d7a5 100644
--- a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.cc
+++ b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.cc
@@ -74,7 +74,7 @@
   return true;
 }
 
-void CssSelectorFragmentAnchor::PerformPreRafActions() {}
+void CssSelectorFragmentAnchor::PerformScriptableActions() {}
 
 void CssSelectorFragmentAnchor::Installed() {}
 
diff --git a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.h b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.h
index 580bbcd..ea83182 100644
--- a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.h
+++ b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor.h
@@ -40,7 +40,7 @@
 
   bool InvokeSelector() override;
 
-  void PerformPreRafActions() override;
+  void PerformScriptableActions() override;
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.cc b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.cc
index 97e8ffa..1acbd10 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.cc
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.cc
@@ -215,97 +215,62 @@
 }
 
 bool TextFragmentAnchor::InvokeSelector() {
-  if (state_ == kDone) {
-    return false;
-  } else if (state_ == kScriptableActions) {
-    // We need to keep this TextFragmentAnchor alive if we're proxying an
-    // element fragment anchor or we're still waiting for a rAF to perform
-    // post-search actions, but in that case InvokeSelector() should be a no-op.
-    return true;
+  // InvokeSelector is called repeatedly during the Blink lifecycle, however,
+  // attachment (i.e. text searching DOM) is an expensive operation.  Perform
+  // it once on the first invoke (after parsing completes) and once again for
+  // any unattached directives the first time InvokeSelector is called after
+  // the load event in case more content was loaded.
+  if (!did_perform_initial_attachment_ ||
+      (!did_perform_post_load_attachment_ &&
+       frame_->GetDocument()->IsLoadCompleted())) {
+    // If this successfully attaches the first directive it will move the anchor
+    // into kBeforeMatchEventQueued state.
+    TryAttachingUnattachedDirectives();
+
+    did_perform_initial_attachment_ = true;
+
+    if (frame_->GetDocument()->IsLoadCompleted())
+      did_perform_post_load_attachment_ = true;
   }
 
-  // Only invoke once, and then a second time once the document is loaded.
-  // Otherwise page load performance could be significantly
-  // degraded, since TextFragmentFinder has O(n) performance. The reason
-  // for invoking twice is to give client-side rendered sites more opportunity
-  // to add text that can participate in text fragment invocation.
-  if (!frame_->GetDocument()->IsLoadCompleted()) {
-    // When parsing is complete the following sequence happens:
-    // 1. Invoke with `state_` == kSearching. This runs a match and
-    //    causes `state_` to be set to kEventQueued, and queues
-    //    a task to set `state_` to be set to kFiredEvent.
-    // 2. (maybe) Invoke with `state_` == kEventQueued.
-    // 3. Invoke with `state_` == kFiredEvent. This runs a match and
-    //    causes `suppress_text_search_until_load_event_` to become true.
-    // 4. Any future calls to Invoke before loading are ignored.
-    //
-    // TODO(chrishtr): if layout is not dirtied, we don't need to re-run
-    // the text finding again and again for each of the above steps.
-    // TODO(bokan): I'm not sure why we proceed if we're queued? It seems like
-    // we could simply return here as well?
-    if (suppress_text_search_until_load_event_ &&
-        (state_ == kSearching || state_ == kBeforeMatchEventFired)) {
-      return true;
-    }
+  switch (state_) {
+    case kSearching:
+      if (frame_->GetDocument()->IsLoadCompleted())
+        DidFinishSearch();
+      break;
+    case kBeforeMatchEventQueued:
+      // If a match was found, we need to wait to fire and process the
+      // BeforeMatch event before doing anything else so don't try to finish
+      // the search yet.
+      break;
+    case kBeforeMatchEventFired:
+      // Now that the event has been processed, apply the necessary effects to
+      // the matching DOM nodes.
+      ApplyEffectsToFirstMatch();
+
+      // A second text-search pass will occur after the load event has been
+      // fired so don't perform any finalization until after that.
+      if (frame_->GetDocument()->IsLoadCompleted())
+        DidFinishSearch();
+      else
+        state_ = kEffectsAppliedKeepInView;
+      break;
+    case kEffectsAppliedKeepInView:
+      // Until the load event ensure the matched text is kept in view in the
+      // face of layout changes.
+      EnsureFirstMatchInViewIfNeeded();
+      if (frame_->GetDocument()->IsLoadCompleted())
+        DidFinishSearch();
+      break;
+    case kScriptableActions:
+      // The search has finished but we're waiting to apply some effects in a
+      // script-safe section. Like above, ensure the match is kept in view.
+      EnsureFirstMatchInViewIfNeeded();
+      break;
+    case kDone:
+      break;
   }
 
-  // TODO(bokan): This is needed since we re-search the text of the document
-  // each time Invoke is called so after the first Invoke creates text markers
-  // subsequent calls will try to create a marker that overlaps and trips our
-  // "no overlapping text fragment" DCHECKs. A followup CL will change this
-  // class to only perform the text search once since further Invoke calls are
-  // used only to continue after a BeforeMatch event or to ensure previously
-  // found matches aren't shifted out of view by layout.
-  // https://crbug.com/1303887.
-  frame_->GetDocument()->Markers().RemoveMarkersOfTypes(
-      DocumentMarker::MarkerTypes::TextFragment());
-
-  if (!did_find_match_) {
-    metrics_->DidStartSearch();
-  }
-
-  // TODO(bokan): Performing attachment is expensive. InvokeSelector is
-  // currently called on each BeginMainFrame to push the state machine forward
-  // but we're performing attachment each time. This is really inefficient and
-  // wasteful. Now that this is all based on AnnotationAgent it should be
-  // straight forward to perform attachment only if a given directive hasn't
-  // yet been matched.
-  // https://crbug.com/1303887.
-  {
-    // DidFinishAttach might cause scrolling and set user_scrolled_ so reset it
-    // when it's done.
-    base::AutoReset<bool> reset_user_scrolled(&user_scrolled_, user_scrolled_);
-
-    metrics_->ResetMatchCount();
-    for (auto& directive_annotation_pair : directive_annotation_pairs_) {
-      AnnotationAgentImpl* annotation = directive_annotation_pair.second;
-      annotation->Attach();
-      bool did_match = DidFinishAttach(*annotation, did_find_match_);
-
-      if (did_match) {
-        metrics_->DidFindMatch();
-        did_find_match_ = true;
-      }
-    }
-  }
-
-  // If we found a match, we need to wait for it to fire before doing anything
-  // else.
-  if (state_ == kBeforeMatchEventQueued)
-    return true;
-
-  // Either no matches were found or we've fired a BeforeMatch event and we
-  // just finished applying the effects to the matched text snippets.
-  DCHECK(state_ == kSearching || state_ == kBeforeMatchEventFired);
-
-  // Stop searching for matching text once the load event has fired. This may
-  // cause ScrollToTextFragment to not work on pages which dynamically load
-  // content: http://crbug.com/963045
-  if (frame_->GetDocument()->IsLoadCompleted())
-    DidFinishSearch();
-  else
-    suppress_text_search_until_load_event_ = true;
-
   // We return true to keep this anchor alive as long as we need another invoke
   // or have to finish up at the next rAF.
   return state_ != kDone;
@@ -313,14 +278,19 @@
 
 void TextFragmentAnchor::Installed() {}
 
-void TextFragmentAnchor::PerformPreRafActions() {
+void TextFragmentAnchor::PerformScriptableActions() {
+  // This is called at the start of each BeginMainFrame regardless of the state
+  // is needed only when waiting to invoke actions that need a script-safe
+  // section.
   if (state_ != kScriptableActions)
     return;
 
+  DCHECK(frame_->GetDocument()->IsLoadCompleted());
+
   if (element_fragment_anchor_) {
     element_fragment_anchor_->Installed();
     element_fragment_anchor_->Invoke();
-    element_fragment_anchor_->PerformPreRafActions();
+    element_fragment_anchor_->PerformScriptableActions();
     element_fragment_anchor_ = nullptr;
   }
 
@@ -342,95 +312,148 @@
   visitor->Trace(element_fragment_anchor_);
   visitor->Trace(metrics_);
   visitor->Trace(directive_annotation_pairs_);
+  visitor->Trace(first_match_);
   SelectorFragmentAnchor::Trace(visitor);
 }
 
-bool TextFragmentAnchor::DidFinishAttach(const AnnotationAgentImpl& annotation,
-                                         bool first_match_found) {
-  if (!annotation.IsAttached())
-    return false;
+void TextFragmentAnchor::TryAttachingUnattachedDirectives() {
+  // TODO(bokan): This sets the start time that's used to report
+  // TimeToScrollIntoView. Using `!first_match` means the start time will
+  // differ based on whether or not we had a match in the first attachment. The
+  // TimeToScrollIntoView means to report how long from parsing until the user
+  // sees the scroll change so the user-invisible timing shouldn't matter.
+  // DidStartSearch should be called once and preferably from
+  // TextFragmentAnchor creation (which is what the histogram's description
+  // says happens...). https://crbug.com/1327734.
+  if (!first_match_)
+    metrics_->DidStartSearch();
 
-  DCHECK_LE(state_, kBeforeMatchEventFired);
+  for (auto& directive_annotation_pair : directive_annotation_pairs_) {
+    AnnotationAgentImpl* annotation = directive_annotation_pair.second;
+    if (annotation->IsAttached())
+      continue;
 
-  if (!static_cast<const TextAnnotationSelector*>(annotation.GetSelector())
-           ->WasMatchUnique()) {
-    metrics_->DidFindAmbiguousMatch();
+    annotation->Attach();
+    if (annotation->IsAttached()) {
+      if (!first_match_)
+        DidFindFirstMatch(*annotation);
+
+      metrics_->DidFindMatch();
+      if (!static_cast<const TextAnnotationSelector*>(annotation->GetSelector())
+               ->WasMatchUnique()) {
+        metrics_->DidFindAmbiguousMatch();
+      }
+    }
   }
+}
 
-  // Everything below is applied only to the first match.
-  if (first_match_found)
-    return true;
+void TextFragmentAnchor::DidFindFirstMatch(
+    const AnnotationAgentImpl& annotation) {
+  DCHECK(annotation.IsAttached());
+  DCHECK_EQ(state_, kSearching);
+  DCHECK(!first_match_);
+
+  first_match_ = &annotation;
 
   const RangeInFlatTree& range = annotation.GetAttachedRange();
 
   // TODO(bokan): This fires an event and reveals only at the first match - it
   // seems like something we may want to do for all highlights on a page?
   // https://crbug.com/1327379.
-  if (state_ == kSearching) {
-    Element* enclosing_block =
-        EnclosingBlock(range.StartPosition(), kCannotCrossEditingBoundary);
-    DCHECK(enclosing_block);
-    frame_->GetDocument()->EnqueueAnimationFrameTask(
-        WTF::Bind(&TextFragmentAnchor::FireBeforeMatchEvent,
-                  WrapPersistent(this), WrapPersistent(&range)));
-    state_ = kBeforeMatchEventQueued;
-    return false;
-  }
-  if (state_ == kBeforeMatchEventQueued)
-    return false;
+  Element* enclosing_block =
+      EnclosingBlock(range.StartPosition(), kCannotCrossEditingBoundary);
+  DCHECK(enclosing_block);
+  frame_->GetDocument()->EnqueueAnimationFrameTask(
+      WTF::Bind(&TextFragmentAnchor::FireBeforeMatchEvent, WrapPersistent(this),
+                WrapPersistent(&range)));
+
+  state_ = kBeforeMatchEventQueued;
+}
+
+void TextFragmentAnchor::ApplyEffectsToFirstMatch() {
+  DCHECK(first_match_);
+  DCHECK_EQ(state_, kBeforeMatchEventFired);
+
   // TODO(jarhar): Consider what to do based on DOM/style modifications made by
   // the beforematch event here and write tests for it once we decide on a
   // behavior here: https://github.com/WICG/display-locking/issues/150
 
+  // It's possible the DOM the match was attached to was removed by this time.
+  if (!first_match_->IsAttached())
+    return;
+
+  const RangeInFlatTree& range = first_match_->GetAttachedRange();
+
   // Apply :target pseudo class.
   ApplyTargetToCommonAncestor(range.ToEphemeralRange());
   frame_->GetDocument()->UpdateStyleAndLayout(
       DocumentUpdateReason::kFindInPage);
 
-  // Perform scroll and related actions.
-  if (should_scroll_ && !user_scrolled_) {
-    DCHECK(range.ToEphemeralRange().Nodes().begin() !=
-           range.ToEphemeralRange().Nodes().end());
+  // Scroll the match into view.
+  if (!EnsureFirstMatchInViewIfNeeded())
+    return;
 
-    annotation.ScrollIntoView();
-
-    if (AXObjectCache* cache = frame_->GetDocument()->ExistingAXObjectCache()) {
-      Node& first_node = *range.ToEphemeralRange().Nodes().begin();
-      cache->HandleScrolledToAnchor(&first_node);
-    }
-
-    metrics_->DidInvokeScrollIntoView();
-
-    // Set the sequential focus navigation to the start of selection.
-    // Even if this element isn't focusable, "Tab" press will
-    // start the search to find the next focusable element from this element.
-    frame_->GetDocument()->SetSequentialFocusNavigationStartingPoint(
-        range.StartPosition().NodeAsRangeFirstNode());
+  if (AXObjectCache* cache = frame_->GetDocument()->ExistingAXObjectCache()) {
+    Node& first_node = *range.ToEphemeralRange().Nodes().begin();
+    cache->HandleScrolledToAnchor(&first_node);
   }
 
+  metrics_->DidInvokeScrollIntoView();
+
+  // Set the sequential focus navigation to the start of selection.
+  // Even if this element isn't focusable, "Tab" press will
+  // start the search to find the next focusable element from this element.
+  frame_->GetDocument()->SetSequentialFocusNavigationStartingPoint(
+      range.StartPosition().NodeAsRangeFirstNode());
+}
+
+bool TextFragmentAnchor::EnsureFirstMatchInViewIfNeeded() {
+  DCHECK(first_match_);
+  DCHECK_GE(state_, kBeforeMatchEventFired);
+
+  if (!should_scroll_ || user_scrolled_)
+    return false;
+
+  // It's possible the DOM the match was attached to was removed by this time.
+  if (!first_match_->IsAttached())
+    return false;
+
+  // Ensure we don't treat the text fragment ScrollIntoView as a user scroll
+  // so reset user_scrolled_ when it's done.
+  base::AutoReset<bool> reset_user_scrolled(&user_scrolled_, user_scrolled_);
+  first_match_->ScrollIntoView();
+
   return true;
 }
 
 void TextFragmentAnchor::DidFinishSearch() {
-  DCHECK_LE(state_, kBeforeMatchEventFired);
-  state_ = kScriptableActions;
+  DCHECK(frame_->GetDocument()->IsLoadCompleted());
+  DCHECK_LE(state_, kEffectsAppliedKeepInView);
 
   metrics_->SetSearchEngineSource(HasSearchEngineSource());
   metrics_->ReportMetrics();
 
-  if (!did_find_match_) {
+  bool did_find_any_matches = first_match_;
+
+  if (!did_find_any_matches) {
     DCHECK(!element_fragment_anchor_);
-    // ElementFragmentAnchor needs to be invoked from PerformPreRafActions
+    // ElementFragmentAnchor needs to be invoked from PerformScriptableActions
     // since it can cause script to run and we may be in a ScriptForbiddenScope
     // here.
     element_fragment_anchor_ = ElementFragmentAnchor::TryCreate(
         frame_->GetDocument()->Url(), *frame_, should_scroll_);
   }
 
-  // There are actions resulting from matching text fragment that can lead to
-  // executing script. These need to happen when script is allowed so schedule
-  // a new frame to perform these final actions.
-  frame_->GetPage()->GetChromeClient().ScheduleAnimation(frame_->View());
+  DCHECK(!did_find_any_matches || !element_fragment_anchor_);
+  state_ = did_find_any_matches || element_fragment_anchor_ ? kScriptableActions
+                                                            : kDone;
+
+  if (state_ == kScriptableActions) {
+    // There are actions resulting from matching text fragment that can lead to
+    // executing script. These need to happen when script is allowed so schedule
+    // a new frame to perform these final actions.
+    frame_->GetPage()->GetChromeClient().ScheduleAnimation(frame_->View());
+  }
 }
 
 void TextFragmentAnchor::ApplyTargetToCommonAncestor(
@@ -448,28 +471,31 @@
 }
 
 void TextFragmentAnchor::FireBeforeMatchEvent(const RangeInFlatTree* range) {
-  // TODO(crbug.com/1252872): Only |first_node| is considered for the below
-  // ancestor expanding code, but we should be considering the entire range
-  // of selected text for ancestor unlocking as well.
-  Node& first_node = *range->ToEphemeralRange().Nodes().begin();
+  if (!range->IsCollapsed() && range->IsConnected()) {
+    // TODO(crbug.com/1252872): Only |first_node| is considered for the below
+    // ancestor expanding code, but we should be considering the entire range
+    // of selected text for ancestor unlocking as well.
+    Node& first_node = *range->ToEphemeralRange().Nodes().begin();
 
-  // Activate content-visibility:auto subtrees if needed.
-  DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(
-      range->ToEphemeralRange());
+    // Activate content-visibility:auto subtrees if needed.
+    DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(
+        range->ToEphemeralRange());
 
-  // If the active match is hidden inside a <details> element, then we should
-  // expand it so we can scroll to it.
-  if (RuntimeEnabledFeatures::AutoExpandDetailsElementEnabled() &&
-      HTMLDetailsElement::ExpandDetailsAncestors(first_node)) {
-    UseCounter::Count(first_node.GetDocument(),
-                      WebFeature::kAutoExpandedDetailsForScrollToTextFragment);
-  }
+    // If the active match is hidden inside a <details> element, then we should
+    // expand it so we can scroll to it.
+    if (RuntimeEnabledFeatures::AutoExpandDetailsElementEnabled() &&
+        HTMLDetailsElement::ExpandDetailsAncestors(first_node)) {
+      UseCounter::Count(
+          first_node.GetDocument(),
+          WebFeature::kAutoExpandedDetailsForScrollToTextFragment);
+    }
 
-  // If the active match is hidden inside a hidden=until-found element, then we
-  // should reveal it so we can scroll to it.
-  if (RuntimeEnabledFeatures::BeforeMatchEventEnabled(
-          first_node.GetExecutionContext())) {
-    DisplayLockUtilities::RevealHiddenUntilFoundAncestors(first_node);
+    // If the active match is hidden inside a hidden=until-found element, then
+    // we should reveal it so we can scroll to it.
+    if (RuntimeEnabledFeatures::BeforeMatchEventEnabled(
+            first_node.GetExecutionContext())) {
+      DisplayLockUtilities::RevealHiddenUntilFoundAncestors(first_node);
+    }
   }
 
   state_ = kBeforeMatchEventFired;
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.h b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.h
index 8a29bf75..1dcba1d 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.h
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.h
@@ -25,6 +25,55 @@
 class KURL;
 class TextDirective;
 
+// TextFragmentAnchor is the coordinator class for applying text directives
+// from the URL (also known as "scroll-to-text") to a document. This class'
+// purpose is to integrate with Blink's loading and lifecycle states. The
+// actual logic of performing the text search and applying highlights is
+// delegated out to the core annotation API.
+//
+// A frame will try to create a TextFragmentAnchor when parsing in a document
+// completes. If the URL has a valid text directive an instance of
+// TextFragmentAnchor will be created and stored on the LocalFrameView.
+//
+// The anchor performs its operations via the InvokeSelector method which is
+// invoked repeatedly, each time layout finishes in the document. Thus, the
+// anchor is guaranteed that layout is clean in InvokeSelector; however,
+// end-of-layout is a script-forbidden section so no actions that can result in
+// script being run can be invoked from there. Scriptable actions will instead
+// cause a BeginMainFrame to be scheduled and run in that frame before the
+// lifecycle, where script is allowed.
+//
+// TextFragmentAnchor is a state machine that transitions state via
+// InvokeSelector (and some external events). Here are the state transitions:
+//
+//           ┌──────┐
+//           │   ┌──┴────────────────────────┐
+//           └───►       kSearching          ├────────────┐
+//               └─────────────┬─────────────┘            │
+//                             │                          │
+//         ┌─────┬─────────────▼─────────────┐            │
+//         └────►│ kBeforeMatchEventQueued   │            │
+//               └─────────────┬─────────────┘            │
+//                             │                          │
+//               ┌─────────────▼─────────────┐            │
+//               │  kBeforeMatchEventFired   ├────────────┤
+//               └─────────────┬─────────────┘            │
+//                             │                          │
+//         ┌─────┬─────────────▼─────────────┐            │
+//         └────►│ kEffectsAppliedKeepInView │            │
+//               └─────────────┬─────────────┘            │
+//                             │                          │
+//               ┌------------─▼-------------┐            │
+//         ┌─────┤     [[SearchFinished]]    |◄───────────┘
+//         │     └-------------┬-------------┘
+//         │                   │
+//         │     ┌─────────────▼─────────────┬─────┐
+//         │     │    kScriptableActions     │◄────┘
+//         │     └───────────────────────────┘
+//         │                   │
+//         │     ┌─────────────▼─────────────┐
+//         └─────►           kDone           │
+//               └───────────────────────────┘
 class CORE_EXPORT TextFragmentAnchor final : public SelectorFragmentAnchor {
  public:
   // When a document is loaded, this method will be called to see if it meets
@@ -58,22 +107,35 @@
 
   void Installed() override;
 
-  void PerformPreRafActions() override;
+  void PerformScriptableActions() override;
 
   void SetTickClockForTesting(const base::TickClock* tick_clock);
 
   void Trace(Visitor*) const override;
 
-  // Returns true if this was a match and it was processed.
-  // `first_match_found` - true if a prior annotation had a match already.
-  bool DidFinishAttach(const AnnotationAgentImpl& annotation,
-                       bool first_match_found);
-
   bool IsTextFragmentAnchor() override { return true; }
 
  private:
+  // Performs attachment (text search for each directive) for each directive
+  // that hasn't yet found a match.
+  void TryAttachingUnattachedDirectives();
+
+  // Called on the first directive to be successfully matched. This will queue
+  // a BeforeMatch event to be fired.
+  void DidFindFirstMatch(const AnnotationAgentImpl& annotation);
+
+  // Called once the BeforeMatch event from above has been processed. CSS
+  // style and scroll into view can now be performed.
+  void ApplyEffectsToFirstMatch();
+
+  // Performs ScrollIntoView so that the first match is visible in the viewport.
+  // Returns true if scrolling was performed, false otherwise.
+  bool EnsureFirstMatchInViewIfNeeded();
+
   // Called when the search is finished. Reports metrics and activates the
-  // element fragment anchor if we didn't find a match.
+  // element fragment anchor if we didn't find a match. If a match was found or
+  // an element fragment is used, moves the anchor into kScriptableActions.
+  // Otherwise, moves to kDone.
   void DidFinishSearch();
 
   void ApplyTargetToCommonAncestor(const EphemeralRangeInFlatTree& range);
@@ -90,31 +152,39 @@
       std::pair<Member<TextDirective>, Member<AnnotationAgentImpl>>;
   HeapVector<DirectiveAnnotationPair> directive_annotation_pairs_;
 
-  // Whether any directives have found a match.
-  bool did_find_match_ = false;
+  // Once the first directive (in specified order) has been successfully
+  // attached to DOM its annotation will be stored in `first_match_`.
+  Member<const AnnotationAgentImpl> first_match_;
 
   // If the text fragment anchor is defined as a fragment directive and we don't
   // find a match, we fall back to the element anchor if it is present.
   Member<ElementFragmentAnchor> element_fragment_anchor_;
 
-  // Set to true after the first matching pass (i.e. no matches found or the
-  // first InvokeSelector after the BeforeMatch event was fired). Used to
-  // prevent repeated searches until the load event for performance reasons.
-  bool suppress_text_search_until_load_event_ = false;
+  // Set to true after the first time InvokeSelector is called.
+  bool did_perform_initial_attachment_ = false;
+
+  // Set to true once InvokeSelector has been called after IsLoadCompleted.
+  bool did_perform_post_load_attachment_ = false;
 
   enum AnchorState {
     // We're still waiting to find any matches. Either a search hasn't yet been
-    // performed or no matches were found.
+    // performed or no matches were found. If no matches were found in the
+    // initial attachment, a second try will occur only after the load event
+    // has fired; InvokeSelector calls before then will be a no-op.
     kSearching,
     // At least one match has been found. The BeforeMatch event was queued and
-    // we need to wait until it fires before we apply highlighting,
-    // scrollIntoView, etc.
+    // InvokeSelector will now be a no-op until BeforeMatch fires and is
+    // processed.
     kBeforeMatchEventQueued,
-    // The BeforeMatch event has been processed, we can now apply highlighting,
-    // scrollIntoView, etc.
+    // The BeforeMatch event has been processed, InvokeSelector will now apply
+    // effects like CSS :target, scrollIntoView, etc.
     kBeforeMatchEventFired,
+    // The first match has been processed and scrolled into view. The anchor is
+    // kept alive in this state until the load event fires. All that's done
+    // during this state is to keep the match centered in the viewport.
+    kEffectsAppliedKeepInView,
     // Effects have been applied but there's still something left to do in a
-    // script-allowed section.
+    // script-allowed section. Entered only after the load event has fired.
     kScriptableActions,
     // All actions completed - the anchor can be disposed.
     kDone
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.cc b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.cc
index f0f2d64..bf66b1f5 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.cc
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.cc
@@ -27,10 +27,6 @@
   ++matches_count_;
 }
 
-void TextFragmentAnchorMetrics::ResetMatchCount() {
-  matches_count_ = 0;
-}
-
 void TextFragmentAnchorMetrics::DidFindAmbiguousMatch() {
   ambiguous_match_ = true;
 }
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.h b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.h
index d8286837..bd06b3e 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.h
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_metrics.h
@@ -48,7 +48,6 @@
   void DidCreateAnchor(int selector_count);
 
   void DidFindMatch();
-  void ResetMatchCount();
 
   void DidFindAmbiguousMatch();
 
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
index 1986f708..4802f12 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
@@ -1284,8 +1284,6 @@
   EXPECT_TRUE(GetDocument().IsLoadCompleted());
   EXPECT_TRUE(GetDocument().HasFinishedParsing());
 
-  RunAsyncMatchingTasks();
-  Compositor().BeginFrame();
   Compositor().BeginFrame();
 
   // Ensure the target text is still in view and stayed centered
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index ccc376d..fe775337 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -2070,7 +2070,7 @@
       WTF::BindRepeating([](WebLocalFrameImpl* local_frame) {
         if (LocalFrameView* view = local_frame->GetFrameView()) {
           if (FragmentAnchor* anchor = view->GetFragmentAnchor())
-            anchor->PerformPreRafActions();
+            anchor->PerformScriptableActions();
         }
       }));
 
diff --git a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
index a8f4057..1cf47343 100644
--- a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
+++ b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
@@ -160,7 +160,7 @@
   FragmentAnchor::Trace(visitor);
 }
 
-void ElementFragmentAnchor::PerformPreRafActions() {
+void ElementFragmentAnchor::PerformScriptableActions() {
   ApplyFocusIfNeeded();
 }
 
diff --git a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
index c3e8043..11cd5fd 100644
--- a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
+++ b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
@@ -55,7 +55,7 @@
   // Attempts to focus the anchor if we couldn't focus right after install
   // (because rendering was blocked at the time). This can cause script to run
   // so we can't do it in Invoke.
-  void PerformPreRafActions() override;
+  void PerformScriptableActions() override;
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h b/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
index 84c13ad..1351014ac 100644
--- a/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
+++ b/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
@@ -52,7 +52,7 @@
   virtual void Installed() = 0;
 
   virtual void DidScroll(mojom::blink::ScrollType type) = 0;
-  virtual void PerformPreRafActions() = 0;
+  virtual void PerformScriptableActions() = 0;
 
   virtual void Trace(Visitor*) const;
 
diff --git a/third_party/blink/renderer/core/testing/mock_clipboard_host.cc b/third_party/blink/renderer/core/testing/mock_clipboard_host.cc
index 0f0b30a..96b4304 100644
--- a/third_party/blink/renderer/core/testing/mock_clipboard_host.cc
+++ b/third_party/blink/renderer/core/testing/mock_clipboard_host.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/common/tokens/tokens.h"
 #include "third_party/blink/renderer/platform/graphics/color_behavior.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace blink {
@@ -40,9 +41,7 @@
   std::move(callback).Run(sequence_number_);
 }
 
-void MockClipboardHost::ReadAvailableTypes(
-    mojom::ClipboardBuffer clipboard_buffer,
-    ReadAvailableTypesCallback callback) {
+Vector<String> MockClipboardHost::ReadStandardFormatNames() {
   Vector<String> types;
   if (!plain_text_.IsEmpty())
     types.push_back("text/plain");
@@ -56,7 +55,14 @@
     CHECK(!base::Contains(types, it.key));
     types.push_back(it.key);
   }
-  std::move(callback).Run(types);
+  return types;
+}
+
+void MockClipboardHost::ReadAvailableTypes(
+    mojom::ClipboardBuffer clipboard_buffer,
+    ReadAvailableTypesCallback callback) {
+  Vector<String> types = ReadStandardFormatNames();
+  std::move(callback).Run(std::move(types));
 }
 
 void MockClipboardHost::IsFormatAvailable(
@@ -173,10 +179,10 @@
 
 void MockClipboardHost::ReadAvailableCustomAndStandardFormats(
     ReadAvailableCustomAndStandardFormatsCallback callback) {
-  Vector<String> format_names;
+  Vector<String> format_names = ReadStandardFormatNames();
   for (const auto& item : unsanitized_custom_data_map_)
     format_names.emplace_back(item.key);
-  std::move(callback).Run(format_names);
+  std::move(callback).Run(std::move(format_names));
 }
 
 void MockClipboardHost::ReadUnsanitizedCustomFormat(
@@ -199,7 +205,9 @@
   // Simulate the underlying platform copying this data.
   Vector<uint8_t> data_copy(base::saturated_cast<wtf_size_t>(data.size()),
                             *data.data());
-  unsanitized_custom_data_map_.Set(format, data_copy);
+  // Append the "web " prefix since it is removed by the clipboard writer during
+  // write.
+  unsanitized_custom_data_map_.Set("web " + format, std::move(data_copy));
 }
 
 #if BUILDFLAG(IS_MAC)
diff --git a/third_party/blink/renderer/core/testing/mock_clipboard_host.h b/third_party/blink/renderer/core/testing/mock_clipboard_host.h
index 73d3fac..74ac69d 100644
--- a/third_party/blink/renderer/core/testing/mock_clipboard_host.h
+++ b/third_party/blink/renderer/core/testing/mock_clipboard_host.h
@@ -67,6 +67,7 @@
 #if BUILDFLAG(IS_MAC)
   void WriteStringToFindPboard(const String& text) override;
 #endif
+  Vector<String> ReadStandardFormatNames();
 
   mojo::ReceiverSet<mojom::blink::ClipboardHost> receivers_;
   ClipboardSequenceNumberToken sequence_number_;
diff --git a/third_party/blink/renderer/modules/clipboard/DEPS b/third_party/blink/renderer/modules/clipboard/DEPS
index d6391a3..4dc7b35 100644
--- a/third_party/blink/renderer/modules/clipboard/DEPS
+++ b/third_party/blink/renderer/modules/clipboard/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
     "+mojo/public/cpp/base/big_buffer.h",
+    "+net/base/mime_util.h",
     "+third_party/blink/renderer/core/clipboard",
     "-third_party/blink/renderer/modules",
     "+third_party/blink/renderer/modules/event_modules.h",
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.cc b/third_party/blink/renderer/modules/clipboard/clipboard.cc
index f08ebfc..50175b1 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -6,11 +6,11 @@
 
 #include <utility>
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h"
 #include "third_party/blink/renderer/core/event_target_names.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/navigator.h"
 #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h"
+#include "ui/base/clipboard/clipboard_constants.h"
 
 namespace blink {
 
@@ -29,13 +29,7 @@
 Clipboard::Clipboard(Navigator& navigator) : Supplement<Navigator>(navigator) {}
 
 ScriptPromise Clipboard::read(ScriptState* script_state) {
-  return read(script_state, ClipboardItemOptions::Create());
-}
-
-ScriptPromise Clipboard::read(ScriptState* script_state,
-                              ClipboardItemOptions* options) {
-  return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state,
-                                         options);
+  return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state);
 }
 
 ScriptPromise Clipboard::readText(ScriptState* script_state) {
@@ -63,6 +57,16 @@
   return GetSupplementable()->DomWindow();
 }
 
+// static
+String Clipboard::ParseWebCustomFormat(const String& format) {
+  String web_custom_format;
+  if (format.StartsWith(ui::kWebClipboardFormatPrefix)) {
+    web_custom_format = format.Substring(
+        static_cast<unsigned>(std::strlen(ui::kWebClipboardFormatPrefix)));
+  }
+  return web_custom_format;
+}
+
 void Clipboard::Trace(Visitor* visitor) const {
   EventTargetWithInlineData::Trace(visitor);
   Supplement<Navigator>::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.h b/third_party/blink/renderer/modules/clipboard/clipboard.h
index 8e2d168b..8b66d45 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -13,7 +13,6 @@
 
 namespace blink {
 
-class ClipboardItemOptions;
 class Navigator;
 class ScriptState;
 
@@ -30,7 +29,6 @@
   Clipboard& operator=(const Clipboard&) = delete;
 
   ScriptPromise read(ScriptState*);
-  ScriptPromise read(ScriptState*, ClipboardItemOptions*);
   ScriptPromise readText(ScriptState*);
 
   ScriptPromise write(ScriptState*, const HeapVector<Member<ClipboardItem>>&);
@@ -40,6 +38,8 @@
   const AtomicString& InterfaceName() const override;
   ExecutionContext* GetExecutionContext() const override;
 
+  static String ParseWebCustomFormat(const String& format);
+
   void Trace(Visitor*) const override;
 };
 
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.idl b/third_party/blink/renderer/modules/clipboard/clipboard.idl
index 01d0dac..0f90bb0 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.idl
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.idl
@@ -12,11 +12,6 @@
      CallWith=ScriptState
     ] Promise<sequence<ClipboardItem>> read();
 
-    [MeasureAs=AsyncClipboardAPIRead,
-     CallWith=ScriptState,
-     RuntimeEnabled=ClipboardCustomFormats
-    ] Promise<sequence<ClipboardItem>> read(ClipboardItemOptions options);
-
     [MeasureAs=AsyncClipboardAPIReadText,
      CallWith=ScriptState
     ] Promise<DOMString> readText();
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_item.cc b/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
index cac0828..9c94308e 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
@@ -4,21 +4,22 @@
 
 #include "third_party/blink/renderer/modules/clipboard/clipboard_item.h"
 
+#include "net/base/mime_util.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/clipboard/clipboard.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/clipboard/clipboard_constants.h"
 
 namespace blink {
 
 // static
 ClipboardItem* ClipboardItem::Create(
     const HeapVector<std::pair<String, ScriptPromise>>& items,
-    const ClipboardItemOptions* options,
     ExceptionState& exception_state) {
-  DCHECK(options);
   // Check that incoming dictionary isn't empty. If it is, it's possible that
   // Javascript bindings implicitly converted an Object (like a ScriptPromise)
   // into {}, an empty dictionary.
@@ -26,18 +27,38 @@
     exception_state.ThrowTypeError("Empty dictionary argument");
     return nullptr;
   }
-  return MakeGarbageCollected<ClipboardItem>(items, options);
+  return MakeGarbageCollected<ClipboardItem>(items);
 }
 
 ClipboardItem::ClipboardItem(
-    const HeapVector<std::pair<String, ScriptPromise>>& items,
-    const ClipboardItemOptions* options)
-    : items_(items) {
-  DCHECK(items_.size());
-  if (options->hasUnsanitized()) {
-    for (const auto& unsanitized_item : options->unsanitized()) {
-      custom_format_items_.push_back(unsanitized_item);
+    const HeapVector<std::pair<String, ScriptPromise>>& items) {
+  DCHECK(items.size());
+  for (const auto& item : items) {
+    String web_custom_format = Clipboard::ParseWebCustomFormat(item.first);
+    if (!web_custom_format.IsEmpty()) {
+      // Types with "web " prefix are special, so we do some level of MIME type
+      // parsing here to get a valid web custom format type.
+      // We want to ensure that the string after removing the "web " prefix is
+      // a valid MIME type.
+      // e.g. "web text/html" is a web custom MIME type & "text/html" is a
+      // well-known MIME type. Removing the "web " prefix makes it hard to
+      // differentiate between the two.
+      std::string web_top_level_mime_type;
+      std::string web_mime_sub_type;
+      if (net::ParseMimeTypeWithoutParameter(web_custom_format.Utf8(),
+                                             &web_top_level_mime_type,
+                                             &web_mime_sub_type)) {
+        String web_custom_format_string = String::Format(
+            "%s%s/%s", ui::kWebClipboardFormatPrefix,
+            web_top_level_mime_type.c_str(), web_mime_sub_type.c_str());
+        items_.emplace_back(web_custom_format_string, item.second);
+        custom_format_items_.push_back(web_custom_format_string);
+        continue;
+      }
     }
+    // Any arbitrary type can be added to ClipboardItem, but there may not be
+    // any read/write support for that type.
+    items_.push_back(item);
   }
 }
 
@@ -54,9 +75,8 @@
                                      const String& type,
                                      ExceptionState& exception_state) const {
   for (const auto& item : items_) {
-    if (type == item.first) {
+    if (type == item.first)
       return item.second;
-    }
   }
 
   exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError,
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_item.h b/third_party/blink/renderer/modules/clipboard/clipboard_item.h
index c665606a..a4fc528 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_item.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_item.h
@@ -12,7 +12,6 @@
 namespace blink {
 
 class ScriptState;
-class ClipboardItemOptions;
 
 class ClipboardItem final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -20,12 +19,10 @@
  public:
   static ClipboardItem* Create(
       const HeapVector<std::pair<String, ScriptPromise>>& items,
-      const ClipboardItemOptions* options,
       ExceptionState& exception_state);
 
   explicit ClipboardItem(
-      const HeapVector<std::pair<String, ScriptPromise>>& items,
-      const ClipboardItemOptions* options);
+      const HeapVector<std::pair<String, ScriptPromise>>& items);
   Vector<String> types() const;
   ScriptPromise getType(ScriptState* script_state,
                         const String& type,
@@ -35,7 +32,7 @@
     return items_;
   }
 
-  // Returns the custom formats passed to direct option.
+  // Returns the custom formats that have a "web " prefix.
   const Vector<String>& CustomFormats() const { return custom_format_items_; }
 
   void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_item.idl b/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
index 3a8a2664..9a50290 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
@@ -8,8 +8,7 @@
   SecureContext,
   Exposed=Window
 ] interface ClipboardItem {
-  [RaisesException] constructor(record<DOMString, Promise<Blob>> items,
-              optional ClipboardItemOptions options = {});
+  [RaisesException] constructor(record<DOMString, Promise<Blob>> items);
   readonly attribute FrozenArray<DOMString> types;
 
   [
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl b/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl
deleted file mode 100644
index c1e1213..0000000
--- a/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl
+++ /dev/null
@@ -1,9 +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.
-
-// https://w3c.github.io/clipboard-apis/#clipboard-interface
-
-dictionary ClipboardItemOptions {
-  [RuntimeEnabled=ClipboardCustomFormats] sequence<DOMString> unsanitized;
-};
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index 307e408..d398e4b 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -15,7 +15,6 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h"
 #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
 #include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -115,16 +114,14 @@
 
 // static
 ScriptPromise ClipboardPromise::CreateForRead(ExecutionContext* context,
-                                              ScriptState* script_state,
-                                              ClipboardItemOptions* options) {
+                                              ScriptState* script_state) {
   if (!script_state->ContextIsValid())
     return ScriptPromise();
   ClipboardPromise* clipboard_promise =
       MakeGarbageCollected<ClipboardPromise>(context, script_state);
   clipboard_promise->GetTaskRunner()->PostTask(
-      FROM_HERE,
-      WTF::Bind(&ClipboardPromise::HandleRead,
-                WrapPersistent(clipboard_promise), WrapPersistent(options)));
+      FROM_HERE, WTF::Bind(&ClipboardPromise::HandleRead,
+                           WrapPersistent(clipboard_promise)));
   return clipboard_promise->script_promise_resolver_->Promise();
 }
 
@@ -215,22 +212,10 @@
   wtf_size_t item_index = custom_format_items_.Find(type);
   if (item_index != kNotFound) {
     clipboard_writer_ =
-        ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this,
-                                /*is_custom_format_type*/ true);
-    if (ClipboardWriter::IsValidType(type, /*is_custom_format_type*/ false)) {
-      // Decrement `clipboard_representation_index_` & remove the format from
-      // the `custom_format_items_` so we can redo the write, but this time, it
-      // will write a sanitized version of the format using the "standard"
-      // format writer. Standard formats include text/html, text/plain,
-      // text/rtf, image/png, text/uri-list & image/svg+xml.
-      // https://github.com/w3c/editing/blob/gh-pages/docs/clipboard-pickling/explainer.md#pickled-version-for-sanitized-formats
-      custom_format_items_.EraseAt(item_index);
-      clipboard_representation_index_--;
-    }
+        ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this);
   } else {
     clipboard_writer_ =
-        ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this,
-                                /*is_custom_format_type*/ false);
+        ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this);
   }
   clipboard_writer_->WriteToSystem(blob);
 }
@@ -245,22 +230,19 @@
           clipboard_item_data_[clipboard_representation_index_].first + "."));
 }
 
-void ClipboardPromise::HandleRead(ClipboardItemOptions* options) {
+void ClipboardPromise::HandleRead() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (options->hasUnsanitized()) {
-    for (const auto& unsanitized_item : options->unsanitized()) {
-      custom_format_items_.push_back(unsanitized_item);
-    }
-  }
   RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ,
-                    !custom_format_items_.IsEmpty(),
+                    /*allow_without_sanitization=*/
+                    RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled(),
                     WTF::Bind(&ClipboardPromise::HandleReadWithPermission,
                               WrapPersistent(this)));
 }
 
 void ClipboardPromise::HandleReadText() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, false,
+  RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ,
+                    /*allow_without_sanitization=*/false,
                     WTF::Bind(&ClipboardPromise::HandleReadTextWithPermission,
                               WrapPersistent(this)));
 }
@@ -299,16 +281,18 @@
   DCHECK(RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() ||
          custom_format_items_.IsEmpty());
 
-  RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE,
-                    !custom_format_items_.IsEmpty(),
-                    WTF::Bind(&ClipboardPromise::HandleWriteWithPermission,
-                              WrapPersistent(this)));
+  RequestPermission(
+      mojom::blink::PermissionName::CLIPBOARD_WRITE,
+      /*allow_without_sanitization=*/!custom_format_items_.IsEmpty(),
+      WTF::Bind(&ClipboardPromise::HandleWriteWithPermission,
+                WrapPersistent(this)));
 }
 
 void ClipboardPromise::HandleWriteText(const String& data) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   plain_text_ = data;
-  RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, false,
+  RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE,
+                    /*allow_without_sanitization=*/false,
                     WTF::Bind(&ClipboardPromise::HandleWriteTextWithPermission,
                               WrapPersistent(this)));
 }
@@ -324,7 +308,7 @@
   }
 
   SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard();
-  if (!custom_format_items_.IsEmpty()) {
+  if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) {
     system_clipboard->ReadAvailableCustomAndStandardFormats(WTF::Bind(
         &ClipboardPromise::OnReadAvailableFormatNames, WrapPersistent(this)));
     return;
@@ -343,9 +327,6 @@
     return;
   }
 
-  ClipboardItemOptions* options = ClipboardItemOptions::Create();
-  options->setUnsanitized(custom_format_items_);
-
   ScriptState::Scope scope(script_state_);
   HeapVector<std::pair<String, ScriptPromise>> items;
   items.ReserveInitialCapacity(clipboard_item_data_.size());
@@ -356,7 +337,7 @@
     items.emplace_back(item.first, promise);
   }
   HeapVector<Member<ClipboardItem>> clipboard_items = {
-      MakeGarbageCollected<ClipboardItem>(items, options)};
+      MakeGarbageCollected<ClipboardItem>(items)};
   script_promise_resolver_->Resolve(clipboard_items);
 }
 
@@ -368,8 +349,7 @@
 
   clipboard_item_data_.ReserveInitialCapacity(format_names.size());
   for (const String& format_name : format_names) {
-    if (ClipboardWriter::IsValidType(
-            format_name, base::Contains(custom_format_items_, format_name))) {
+    if (ClipboardWriter::IsValidType(format_name)) {
       clipboard_item_data_.emplace_back(format_name,
                                         /* Placeholder value. */ nullptr);
     }
@@ -390,8 +370,7 @@
       clipboard_item_data_[clipboard_representation_index_].first;
 
   ClipboardReader* clipboard_reader = ClipboardReader::Create(
-      GetLocalFrame()->GetSystemClipboard(), format_name, this,
-      base::Contains(custom_format_items_, format_name));
+      GetLocalFrame()->GetSystemClipboard(), format_name, this);
   if (!clipboard_reader) {
     OnRead(nullptr);
     return;
@@ -469,8 +448,7 @@
     const String& type = type_and_promise_to_blob.first;
     clipboard_item_types_.emplace_back(type);
     promise_list.emplace_back(type_and_promise_to_blob.second);
-    bool is_valid_custom_format = base::Contains(custom_format_items_, type);
-    if (!ClipboardWriter::IsValidType(type, is_valid_custom_format)) {
+    if (!ClipboardWriter::IsValidType(type)) {
       script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
           DOMExceptionCode::kNotAllowedError,
           "Type " + type + " not supported on write."));
@@ -559,7 +537,8 @@
       LocalFrame::HasTransientUserActivation(GetLocalFrame());
   base::UmaHistogramBoolean("Blink.Clipboard.HasTransientUserActivation",
                             has_transient_user_activation);
-  if (!custom_format_items_.IsEmpty() && !has_transient_user_activation) {
+  if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() &&
+      !has_transient_user_activation) {
     script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
         DOMExceptionCode::kSecurityError,
         "Must be handling a user gesture to use custom clipboard"));
@@ -586,7 +565,8 @@
   // Check permission, and query if necessary.
   // See crbug.com/795929 for moving this check into the Browser process.
   permission_service_->RequestPermission(std::move(permission_descriptor),
-                                         false, std::move(callback));
+                                         /*user_gesture*/ false,
+                                         std::move(callback));
 }
 
 LocalFrame* ClipboardPromise::GetLocalFrame() const {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
index 28c5184..ceee63a 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -31,9 +31,7 @@
                                public ExecutionContextLifecycleObserver {
  public:
   // Creates promise to execute Clipboard API functions off the main thread.
-  static ScriptPromise CreateForRead(ExecutionContext*,
-                                     ScriptState*,
-                                     ClipboardItemOptions*);
+  static ScriptPromise CreateForRead(ExecutionContext*, ScriptState*);
   static ScriptPromise CreateForReadText(ExecutionContext*, ScriptState*);
   static ScriptPromise CreateForWrite(ExecutionContext*,
                                       ScriptState*,
@@ -70,7 +68,7 @@
   void WriteNextRepresentation();
 
   // Checks Read/Write permission (interacting with PermissionService).
-  void HandleRead(ClipboardItemOptions*);
+  void HandleRead();
   void HandleReadText();
   void HandleWrite(HeapVector<Member<ClipboardItem>>*);
   void HandleWriteText(const String&);
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
index c37ee70..19a3a84c 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/modules/clipboard/clipboard.h"
 #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h"
 #include "third_party/blink/renderer/modules/clipboard/clipboard_writer.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
@@ -305,12 +306,14 @@
 // static
 ClipboardReader* ClipboardReader::Create(SystemClipboard* system_clipboard,
                                          const String& mime_type,
-                                         ClipboardPromise* promise,
-                                         bool is_custom_format_type) {
-  DCHECK(ClipboardWriter::IsValidType(mime_type, is_custom_format_type));
-  // If this is a custom format then read the unsanitized version.
-  if (is_custom_format_type &&
-      RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) {
+                                         ClipboardPromise* promise) {
+  DCHECK(ClipboardWriter::IsValidType(mime_type));
+  // If this is a web custom format then read the unsanitized version.
+  if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() &&
+      !Clipboard::ParseWebCustomFormat(mime_type).IsNull()) {
+    // We read the custom MIME type that has the "web " prefix.
+    // These MIME types are found in the web custom format map written by
+    // native applications.
     return MakeGarbageCollected<ClipboardCustomFormatReader>(
         system_clipboard, promise, mime_type);
   }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.h b/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
index abbf2dc..1e123431 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
@@ -43,8 +43,7 @@
   // ClipboardWriter::IsValidType() must return true for `mime_type`.
   static ClipboardReader* Create(SystemClipboard* system_clipboard,
                                  const String& mime_type,
-                                 ClipboardPromise* promise,
-                                 bool is_custom_format_type);
+                                 ClipboardPromise* promise);
   virtual ~ClipboardReader();
 
   // Reads from the system clipboard and encodes on a background thread.
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
index 9ef088c..aa8421a6 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/modules/clipboard/clipboard.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -23,6 +24,7 @@
 #include "third_party/blink/renderer/platform/wtf/cross_thread_copier_skia.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/wtf/wtf.h"
+#include "ui/base/clipboard/clipboard_constants.h"
 
 namespace blink {
 
@@ -258,13 +260,17 @@
 // static
 ClipboardWriter* ClipboardWriter::Create(SystemClipboard* system_clipboard,
                                          const String& mime_type,
-                                         ClipboardPromise* promise,
-                                         bool is_custom_format_type) {
-  DCHECK(ClipboardWriter::IsValidType(mime_type, is_custom_format_type));
-  if (is_custom_format_type &&
-      RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) {
+                                         ClipboardPromise* promise) {
+  DCHECK(ClipboardWriter::IsValidType(mime_type));
+  if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() &&
+      !Clipboard::ParseWebCustomFormat(mime_type).IsEmpty()) {
+    // We write the custom MIME type without the "web " prefix into the web
+    // custom format map so native applications don't have to add any string
+    // parsing logic to read format from clipboard.
     return MakeGarbageCollected<ClipboardCustomFormatWriter>(
-        system_clipboard, promise, mime_type);
+        system_clipboard, promise,
+        mime_type.Substring(
+            static_cast<unsigned>(std::strlen(ui::kWebClipboardFormatPrefix))));
   }
   if (mime_type == kMimeTypeImagePng) {
     return MakeGarbageCollected<ClipboardImageWriter>(system_clipboard,
@@ -299,11 +305,10 @@
 }
 
 // static
-bool ClipboardWriter::IsValidType(const String& type,
-                                  bool is_custom_format_type) {
-  if (is_custom_format_type) {
-    return RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() &&
-           type.length() < mojom::blink::ClipboardHost::kMaxFormatSize;
+bool ClipboardWriter::IsValidType(const String& type) {
+  if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() &&
+      !Clipboard::ParseWebCustomFormat(type).IsEmpty()) {
+    return type.length() < mojom::blink::ClipboardHost::kMaxFormatSize;
   }
   if (type == kMimeTypeImageSvg)
     return RuntimeEnabledFeatures::ClipboardSvgEnabled();
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
index 278f1042..9777696 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
@@ -57,8 +57,7 @@
   // IsValidType() must return true on types passed into `mime_type`.
   static ClipboardWriter* Create(SystemClipboard* system_clipboard,
                                  const String& mime_type,
-                                 ClipboardPromise* promise,
-                                 bool is_custom_format_type);
+                                 ClipboardPromise* promise);
 
   ~ClipboardWriter() override;
 
@@ -70,7 +69,7 @@
   // IsValidType() is used for both ClipboardWriter and ClipboardReader, as read
   // and write currently support the same types. If this changes in the future,
   // please create separate IsValidType functions.
-  static bool IsValidType(const String& mime_type, bool is_custom_format_type);
+  static bool IsValidType(const String& mime_type);
   // Begins the sequence of writing the Blob to the system clipbaord.
   void WriteToSystem(Blob* blob);
 
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc
index bdd4cefb..4262a50 100644
--- a/third_party/blink/renderer/platform/graphics/image.cc
+++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -88,13 +88,13 @@
     DEFINE_THREAD_SAFE_STATIC_LOCAL(
         cc::SoftwareImageDecodeCache, image_decode_cache,
         (kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
-         PaintImage::kDefaultGeneratorClientId));
+         PaintImage::GetNextGeneratorClientId()));
     return image_decode_cache;
   }
   DEFINE_THREAD_SAFE_STATIC_LOCAL(cc::SoftwareImageDecodeCache,
                                   image_decode_cache,
                                   (kN32_SkColorType, kLockedMemoryLimitBytes,
-                                   PaintImage::kDefaultGeneratorClientId));
+                                   PaintImage::GetNextGeneratorClientId()));
   return image_decode_cache;
 }
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index aaf5bdbc..a64ab1b 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1630,7 +1630,7 @@
       // TODO(crbug.com/920069): Remove OffsetParentNewSpecBehavior after the
       // feature is in stable with no issues.
       name: "OffsetParentNewSpecBehavior",
-      status: "stable"
+      status: "experimental"
     },
     {
       name: "OnDeviceChange",
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
index bd62869..27b40787 100644
--- a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
+++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -320,7 +320,7 @@
             raise Exception(
                 'build %s on builder %s expected to have at least one web test '
                 'step, instead has none' %
-                (build.builder_number, build.builder_name))
+                (build.build_number, build.builder_name))
         return suites
 
     @memoized
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 a835d91c..e6f5913 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
@@ -1734,6 +1734,12 @@
             'base::Value',
         ],
     },
+    {
+        'paths': ['third_party/blink/renderer/modules/clipboard/'],
+        'allowed': [
+            'net::ParseMimeTypeWithoutParameter',
+        ],
+    },
 ]
 
 
diff --git a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py
index 9dc929fb..9749778e3c 100644
--- a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py
+++ b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py
@@ -52,16 +52,22 @@
                 host.filesystem.read_text_file(ANDROID_DISABLED_TESTS)})
         self._baseline_expectations = TestExpectations(self.port)
         assert(len(self.options.android_product) == 1)
-        product = self.options.android_product[0]
-        if product == ANDROID_WEBLAYER:
+        self.product = self.options.android_product[0]
+        if self.product == ANDROID_WEBLAYER:
             self.testid_prefix = "ninja://weblayer/shell/android:weblayer_shell_wpt/"
-            self.test_suite = "weblayer_shell_wpt"
-        elif product == ANDROID_WEBVIEW:
+        elif self.product == ANDROID_WEBVIEW:
             self.testid_prefix = "ninja://android_webview/test:system_webview_wpt/"
-            self.test_suite = "system_webview_wpt"
-        elif product == CHROME_ANDROID:
+        elif self.product == CHROME_ANDROID:
             self.testid_prefix = "ninja://chrome/android:chrome_public_wpt/"
-            self.test_suite = "chrome_public_wpt"
+
+    def _test_suite(self, builder_name, flag_specific=None):
+        if self.product == ANDROID_WEBLAYER:
+            return 'weblayer_shell_wpt'
+        elif self.product == ANDROID_WEBVIEW:
+            return 'system_webview_wpt'
+        elif self.product == CHROME_ANDROID:
+            return 'chrome_public_wpt'
+        raise ValueError('unrecognized android product: %r' % self.product)
 
     def expectations_files(self):
         # We need to put all the Android expectation files in
@@ -181,7 +187,7 @@
                 results_from_expectation = set([ResultType.Failure])
         return results_from_expectation
 
-    def write_to_test_expectations(self, test_to_results):
+    def write_to_test_expectations(self, test_to_results, flag_specific=None):
         """Each expectations file is browser specific, and currently only
         runs on pie. Therefore we do not need any configuration specifiers
         to anotate expectations for certain builds.
diff --git a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py
index 653571b6..4bb53c2c 100644
--- a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py
@@ -55,9 +55,12 @@
         host.builders = BuilderList({
             'MOCK Android Weblayer - Pie': {
                 'port_name': 'test-android-pie',
-                'specifiers': ['Precise', 'Release',
-                               'anDroid', 'android_Weblayer'],
+                'specifiers':
+                ['Precise', 'Release', 'anDroid', 'android_Weblayer'],
                 'is_try_builder': True,
+                'steps': {
+                    'weblayer_shell_wpt (with patch)': {},
+                },
             },
         })
 
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py
index f15d5d8..99c09f4 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -255,7 +255,7 @@
         try_results = cl_status.try_job_results
 
         if try_results and self.git_cl.some_failed(try_results):
-            self.fetch_new_expectations_and_baselines()
+            self.fetch_new_expectations_and_baselines(try_results)
             self.fetch_wpt_override_expectations()
             if self.chromium_git.has_working_directory_changes():
                 # Skip slow and timeout tests so that presubmit check passes
@@ -667,7 +667,7 @@
             return ''
         return data['emails'][0]
 
-    def fetch_new_expectations_and_baselines(self):
+    def fetch_new_expectations_and_baselines(self, try_results):
         """Modifies expectation lines and baselines based on try job results.
 
         Assuming that there are some try job results available, this
@@ -676,15 +676,27 @@
 
         This is the same as invoking the `wpt-update-expectations` script.
         """
-        _log.info('Adding test expectations lines to TestExpectations.')
-        self.rebaselined_tests, self.new_test_expectations = (
-            self._expectations_updater.update_expectations())
+        flag_specific_options = set()
+        for build, status in try_results.items():
+            if status.result != 'FAILURE':
+                continue
+            for step_name in self.host.builders.step_names_for_builder(
+                    build.builder_name):
+                option = self.host.builders.flag_specific_option(
+                    build.builder_name, step_name)
+                if option:
+                    flag_specific_options.add(option)
 
-        _log.info('Adding test expectations lines for disable-layout-ng')
-        self._expectations_updater.update_expectations_for_flag_specific('disable-layout-ng')
-
-        _log.info('Adding test expectations lines for disable-site-isolation-trials')
-        self._expectations_updater.update_expectations_for_flag_specific('disable-site-isolation-trials')
+        # Update generic expectations first.
+        for option in [None] + list(flag_specific_options):
+            expectations_file = ('FlagExpectations/%s' %
+                                 option if option else 'TestExpectations')
+            _log.info('Adding test expectation lines for %s.',
+                      expectations_file)
+            rebaselined_tests, new_expectations = (
+                self._expectations_updater.update_expectations(option))
+            self.rebaselined_tests.update(rebaselined_tests)
+            self.new_test_expectations.update(new_expectations)
 
     def fetch_wpt_override_expectations(self):
         """Modifies WPT Override expectations based on try job results.
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
index 4b22d88..11c26a2 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -114,7 +114,7 @@
             try_job_results={
                 Build('builder-a', 123): TryJobStatus('COMPLETED', 'FAILURE'),
             })
-        importer.fetch_new_expectations_and_baselines = lambda: None
+        importer.fetch_new_expectations_and_baselines = lambda _: None
         importer.fetch_wpt_override_expectations = lambda: None
         success = importer.update_expectations_for_cl()
         self.assertTrue(success)
@@ -176,7 +176,7 @@
                 Build('cq-builder-b', 200): TryJobStatus(
                     'COMPLETED', 'SUCCESS'),
             })
-        importer.fetch_new_expectations_and_baselines = lambda: None
+        importer.fetch_new_expectations_and_baselines = lambda _: None
         success = importer.run_commit_queue_for_cl()
         self.assertFalse(success)
         self.assertLog([
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
index 9a73ec7..b5d979f5 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -75,7 +75,6 @@
         self._test_expectations = TestExpectations(
             self.port, expectations_dict=expectations_dict)
         self.testid_prefix = "ninja://:blink_web_tests/"
-        self.test_suite = "blink_web_tests"
 
     def expectations_files(self):
         """Returns list of expectations files.
@@ -157,68 +156,13 @@
                  'This command line argument can be used to mark tests '
                  'as flaky.')
 
-    def update_expectations_for_flag_specific(self, flag_specific):
+    def update_expectations(self, flag_specific=None):
         """Downloads new baselines and adds test expectations lines.
 
         Returns:
             A pair: A set of tests that are rebaselined, and a dictionary
             mapping tests that couldn't be rebaselined to lists of expectation
-            lines written to flag specific test expectations.
-        """
-        self.port.wpt_manifest.cache_clear()
-
-        issue_number = self.get_issue_number()
-        if issue_number == 'None':
-            raise ScriptError('No issue on current branch.')
-
-        if flag_specific == "disable-site-isolation-trials":
-            builder_names = ["linux-rel"]
-            test_suite = "not_site_per_process_blink_web_tests"
-        else:
-            builder_names = self.host.builders.all_flag_specific_try_builder_names(
-                flag_specific)
-            test_suite = "blink_web_tests"
-
-        build_to_status = self.git_cl.latest_try_jobs(
-            builder_names=builder_names,
-            patchset=self.patchset)
-        if not build_to_status:
-            raise ScriptError('No try job information was collected.')
-
-        # Here we build up a dict of failing test results for all platforms.
-        test_expectations = {}
-        for build, job_status in build_to_status.items():
-            if (job_status.result == 'SUCCESS' and
-                    not self.options.include_unexpected_pass):
-                continue
-            # Temporary logging for https://crbug.com/1154650
-            result_dicts = self.get_failing_results_dicts(build, test_suite)
-            _log.info('Merging failing results dicts for %s', build)
-            for result_dict in result_dicts:
-                test_expectations = self.merge_dicts(
-                    test_expectations, result_dict)
-
-        generic_expectations = TestExpectations(self.port)
-
-        # do not create baseline for flag-specific builders yet
-        # rebaselined_tests, test_expectations = self.download_text_baselines(
-        #    test_expectations, flag_specific)
-
-        # Do not create expectations for tests which should have baseline
-        _, test_expectations = self.get_tests_to_rebaseline(
-            test_expectations)
-        exp_lines_dict = self.write_to_test_expectations(test_expectations,
-                                                         flag_specific,
-                                                         generic_expectations)
-        return [], exp_lines_dict
-
-    def update_expectations(self):
-        """Downloads new baselines and adds test expectations lines.
-
-        Returns:
-            A pair: A set of tests that are rebaselined, and a dictionary
-            mapping tests that couldn't be rebaselined to lists of expectation
-            lines written to TestExpectations.
+            lines written to 'TestExpectations' or 'FlagSpecificExpectations/*'.
         """
         # The wpt_manifest function in Port is cached by default, but may be out
         # of date if this code is called during test import. An out of date
@@ -231,20 +175,24 @@
         if issue_number == 'None':
             raise ScriptError('No issue on current branch.')
 
-        build_to_status = self.get_latest_try_jobs(True)
-        _log.debug('Latest try jobs: %r', build_to_status)
+        build_to_status = self.get_latest_try_jobs(flag_specific)
         if not build_to_status:
             raise ScriptError('No try job information was collected.')
+        _log.debug('Latest try jobs:')
+        for build, status in build_to_status.items():
+            _log.debug('  %r: %r', build, status)
 
         # Here we build up a dict of failing test results for all platforms.
         test_expectations = {}
-        for build, job_status in build_to_status.items():
+        for build, job_status in sorted(build_to_status.items()):
             if (job_status.result == 'SUCCESS' and
                     not self.options.include_unexpected_pass):
                 continue
+            test_suite = self._test_suite(build.builder_name, flag_specific)
             # Temporary logging for https://crbug.com/1154650
-            result_dicts = self.get_failing_results_dicts(build, self.test_suite)
-            _log.info('Merging failing results dicts for %s', build)
+            result_dicts = self.get_failing_results_dicts(build, test_suite)
+            _log.info('Merging failing results dicts for %s build %d.',
+                      build.builder_name, build.build_number)
             for result_dict in result_dicts:
                 test_expectations = self.merge_dicts(
                     test_expectations, result_dict)
@@ -257,14 +205,16 @@
         #     }
         # }
 
-        self.add_results_for_configs_without_results(
-            test_expectations, self.configs_with_no_results)
-
-        # And then we merge results for different platforms that had the same results.
-        for test_name, platform_result in test_expectations.items():
-            # platform_result is a dict mapping platforms to results.
-            test_expectations[test_name] = self.merge_same_valued_keys(
-                platform_result)
+        # Each flag-specific suite is coupled to a single port, so the suite's
+        # expectations do not need platform tags.
+        if not flag_specific:
+            self.add_results_for_configs_without_results(
+                test_expectations, self.configs_with_no_results)
+            # Merge results for different platforms that had the same results.
+            test_expectations = {
+                test_name: self.merge_same_valued_keys(platform_result)
+                for test_name, platform_result in test_expectations.items()
+            }
 
         # At this point, test_expectations looks like: {
         #     'test-with-failing-result': {
@@ -274,10 +224,30 @@
         # }
 
         rebaselined_tests, test_expectations = self.download_text_baselines(
-            test_expectations)
-        exp_lines_dict = self.write_to_test_expectations(test_expectations)
+            test_expectations, flag_specific)
+        exp_lines_dict = self.write_to_test_expectations(
+            test_expectations, flag_specific)
         return rebaselined_tests, exp_lines_dict
 
+    def _test_suite(self, builder_name, flag_specific=None):
+        """Find which test suite on a builder runs with a flag."""
+        builders = self.host.builders
+        step_names = [
+            step for step in builders.step_names_for_builder(builder_name)
+            if flag_specific == builders.flag_specific_option(
+                builder_name, step)
+        ]
+        if len(step_names) > 1:
+            raise ValueError(
+                'builder %r has steps %s that run flag-specific suite '
+                '%r (builder list probably misconfigured)' %
+                (builder_name, ', '.join(step_names), flag_specific))
+        elif step_names:
+            # Remove a possible suffix in the step name like '(with patch,
+            # experimental)'.
+            return re.sub('\s*\(.*\)$', '', step_names[0])
+        return 'blink_web_tests'
+
     def add_results_for_configs_without_results(self, test_expectations,
                                                 configs_with_no_results):
         # Handle any platforms with missing results.
@@ -328,13 +298,23 @@
         """Returns current CL number. Can be replaced in unit tests."""
         return self.git_cl.get_issue_number()
 
-    def get_latest_try_jobs(self, exclude_flag_specific):
+    def get_latest_try_jobs(self, flag_specific=None):
         """Returns the latest finished try jobs as Build objects."""
-        builder_names = self._get_try_bots()
-        if exclude_flag_specific:
-            all_flag_specific = self.host.builders.all_flag_specific_try_builder_names("*")
-            builder_names = [b for b in builder_names if b not in all_flag_specific]
-
+        builder_names = set(self._get_try_bots())
+        builders = self.host.builders
+        if flag_specific:
+            builder_names &= set(
+                self.host.builders.all_flag_specific_try_builder_names(
+                    flag_specific))
+        else:
+            flag_spec_only_builders = set()
+            for builder_name in builder_names:
+                step_names = builders.step_names_for_builder(builder_name)
+                if all(
+                        builders.flag_specific_option(builder_name, step_name)
+                        for step_name in step_names):
+                    flag_spec_only_builders.add(builder_name)
+            builder_names -= flag_spec_only_builders
         return self.git_cl.latest_try_jobs(builder_names=builder_names,
                                            patchset=self.patchset)
 
@@ -394,7 +374,8 @@
 
         webdriver_test_results = filter(None, webdriver_test_results)
         if not test_results_list and not webdriver_test_results:
-            _log.warning('No results for build %s', build)
+            _log.warning('No results for %s build %d.', build.builder_name,
+                         build.build_number)
             self.configs_with_no_results.extend(self.get_builder_configs(build))
             return []
 
@@ -696,57 +677,7 @@
             system_remover.remove_os_versions(test, versions)
         system_remover.update_expectations()
 
-    def create_line_dict_for_flag_specific(self, merged_results, generic_expectations):
-        """Creates list of test expectations lines for flag specific builder.
-
-        Traverses through the given |merged_results| dictionary and parses the
-        value to create one test expectations line per key. If a test expectation
-        from generic expectations can be inherited, we will reuse that expectation
-        so that we can keep the file size small. Flag specific expectations
-        does not use platform tag, so we don't need handle conflicts either.
-
-        Test expectation lines have the following format:
-            ['BUG_URL TEST_NAME [EXPECTATION(S)]']
-
-        Args:
-            merged_results: A dictionary with the format:
-                {
-                    'test-with-failing-result': {
-                        (config1,): SimpleTestResult
-                    }
-                }
-
-        Returns:
-            line_dict: A dictionary from test names to a list of test
-                       expectation lines
-                       (each SimpleTestResult turns into a line).
-            configs_to_remove: An empty dictionary
-        """
-        line_dict = defaultdict(list)
-        for test_name, test_results in sorted(merged_results.items()):
-            if not self._is_wpt_test(test_name):
-                _log.warning(
-                    'Non-WPT test "%s" unexpectedly passed to create_line_dict.',
-                    test_name)
-                continue
-            expectation_line = generic_expectations.get_expectations(test_name)
-            expectations = expectation_line.results
-            for configs, result in sorted(test_results.items()):
-                new_expectations = self.get_expectations(result, test_name)
-                if 'Failure' in new_expectations:
-                    new_expectations.remove('Failure')
-                    new_expectations.add('FAIL')
-                if new_expectations != expectations:
-                    line_dict[test_name].extend(
-                        self._create_lines(test_name, [], result))
-                # for flag-specific builders, we always have one config for each
-                # test, so quit the loop here
-                break
-
-        return line_dict, {}
-
-
-    def create_line_dict(self, merged_results):
+    def create_line_dict(self, merged_results, flag_specific=None):
         """Creates list of test expectations lines.
 
         Traverses through the given |merged_results| dictionary and parses the
@@ -766,20 +697,24 @@
 
         Returns:
             line_dict: A dictionary from test names to a list of test
-                       expectation lines
-                       (each SimpleTestResult turns into a line).
+                expectation lines (each SimpleTestResult turns into a line).
             configs_to_remove: A dictionary from test names to a set
-                               of os specifiers
+                of OS specifiers.
         """
         line_dict = defaultdict(list)
         configs_to_remove = defaultdict(set)
+        generic_expectations = TestExpectations(self.port)
         for test_name, test_results in sorted(merged_results.items()):
             if not self._is_wpt_test(test_name):
                 _log.warning(
                     'Non-WPT test "%s" unexpectedly passed to create_line_dict.',
                     test_name)
                 continue
-            for configs, result in sorted(test_results.items()):
+            test_results = sorted(test_results.items())
+            if flag_specific:
+                test_results = self._truncate_results(generic_expectations,
+                                                      test_name, test_results)
+            for configs, result in test_results:
                 line_dict[test_name].extend(
                     self._create_lines(test_name, configs, result))
                 for config in configs:
@@ -789,6 +724,26 @@
 
         return line_dict, configs_to_remove
 
+    def _truncate_results(self, generic_expectations, test_name, test_results):
+        """Truncate a test's results to a single line, at most.
+
+        This filter may yield a line if the generic expectations do not already
+        encompass the flag-specific result.
+        """
+        expectations = generic_expectations.get_expectations(test_name).results
+        # For flag-specific builders, each test always has one config, so pick
+        # any.
+        if not test_results:
+            return
+        _, result = test_results[0]
+        new_expectations = self.get_expectations(result, test_name)
+        if 'Failure' in new_expectations:
+            new_expectations.remove('Failure')
+            new_expectations.add('FAIL')
+        new_expectations = {result.upper() for result in new_expectations}
+        if new_expectations != expectations:
+            yield [], result
+
     def _create_lines(self, test_name, configs, result):
         """Constructs test expectation line strings.
 
@@ -927,8 +882,7 @@
         return frozenset(all_platform_specifiers)
 
     def write_to_test_expectations(self, test_expectations,
-                                   flag_specific=None,
-                                   generic_expectations=None):
+                                   flag_specific=None):
         """Writes the given lines to the TestExpectations file.
 
         The place in the file where the new lines are inserted is after a marker
@@ -941,19 +895,19 @@
         Args:
             test_expectations: A dictionary mapping test names to a dictionary
             mapping platforms and test results.
+            flag_specific (Optional[str]): The flag-specific option name (ex:
+                'highdpi'), or `None` for generic 'blink_web_tests'.
+
         Returns:
             Dictionary mapping test names to lists of test expectation strings.
         """
-        if flag_specific:
-            line_dict, configs_to_remove = self.create_line_dict_for_flag_specific(
-                test_expectations, generic_expectations)
-        else:
-            line_dict, configs_to_remove = self.create_line_dict(test_expectations)
+        line_dict, configs_to_remove = self.create_line_dict(
+            test_expectations, flag_specific)
         if not line_dict:
-            _log.info(
-                'No lines to write to %s, WebdriverExpectations'
-                ' or NeverFixTests.' % (flag_specific or 'TestExpectations')
-            )
+            expectations_file = ('FlagExpectations/%s' % flag_specific
+                                 if flag_specific else 'TestExpectations')
+            _log.info('No lines to write to %s, WebdriverExpectations'
+                      ' or NeverFixTests.' % expectations_file)
             return {}
 
         if configs_to_remove:
@@ -986,8 +940,9 @@
             if not lines:
                 continue
 
-            _log.info('Lines to write to %s:\n %s', expectations_file_path,
-                      '\n'.join(lines))
+            _log.info('Lines to write to %s:', expectations_file_path)
+            for line in lines:
+                _log.info('  %s', line)
             # Writes to TestExpectations file.
             file_contents = self.host.filesystem.read_text_file(
                 expectations_file_path)
@@ -1293,9 +1248,10 @@
             command.append('--patchset=' + str(self.patchset))
         command += tests_to_rebaseline
         rebaseline_output = self.host.executive.run_command(command)
-        _log.info(
-            "Output of rebaseline-cl:\n%s\n--end of rebaseline-cl output --" %
-            rebaseline_output)
+        _log.info('Output of rebaseline-cl:')
+        for line in rebaseline_output.splitlines():
+            _log.info('  %s', line)
+        _log.info('-- end of rebaseline-cl output --')
         return tests_to_rebaseline, test_results
 
     def get_tests_to_rebaseline(self, test_results):
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
index 0e89ac6..e51be0c 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -4,6 +4,9 @@
 
 import copy
 import json
+import sys
+
+import six
 
 from blinkpy.common.host_mock import MockHost
 from blinkpy.common.net.git_cl import TryJobStatus
@@ -41,11 +44,17 @@
                 'port_name': 'test-mac-mac10.10',
                 'specifiers': ['Mac10.10', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Try Mac10.11': {
                 'port_name': 'test-mac-mac10.11',
                 'specifiers': ['Mac10.11', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Try Trusty': {
                 'port_name': 'test-linux-trusty',
@@ -53,27 +62,43 @@
                 'main': 'tryserver.blink',
                 'has_webdriver_tests': True,
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Try Precise': {
                 'port_name': 'test-linux-precise',
                 'specifiers': ['Precise', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Try Win10': {
                 'port_name': 'test-win-win10',
                 'specifiers': ['Win10', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Try Win7': {
                 'port_name': 'test-win-win7',
                 'specifiers': ['Win7', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK highdpi': {
                 'port_name': 'test-linux-trusty',
                 'specifiers': ['Trusty', 'Release'],
-                'flag_specific': 'highdpi',
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {
+                        'flag_specific': 'highdpi',
+                    },
+                },
             },
         })
 
@@ -161,14 +186,87 @@
             [json.loads(result)] * 3)
 
         self.assertEqual(0, updater.run())
-
         self.assertEqual(
             host.filesystem.read_text_file(expectations_path),
             '# ====== New tests from wpt-importer added here ======\n'
             'crbug.com/626703 [ Mac10.10 ] external/wpt/test/path.html [ Timeout ]\n'
         )
 
-    def test_cmd_arg_include_unexpected_pass_raieses_exception(self):
+    def test_update_expectations_for_flag_specific(self):
+        host = self.mock_host()
+        updater = WPTExpectationsUpdater(host)
+        updater.git_cl = MockGitCL(updater.host, {
+            Build('MOCK highdpi', 123):
+            TryJobStatus('COMPLETED', 'FAILURE'),
+        })
+        flag_exp_path = updater.port.path_to_flag_specific_expectations_file(
+            'highdpi')
+        host.filesystem.write_text_file(
+            updater.port.path_to_generic_test_expectations_file(),
+            '# results: [ Timeout Crash Pass Failure Skip ]\n'
+            '# The importer should not create a redundant line in \n'
+            '# "FlagExpectations/highdpi" for this test.\n'
+            'crbug.com/123 external/wpt/test/crash1.html [ Crash ]\n')
+        host.filesystem.write_text_file(
+            flag_exp_path, '# results: [ Timeout Crash Pass Failure Skip ]\n')
+        host.results_fetcher.set_results_to_resultdb(
+            Build('MOCK highdpi', 123), [{
+                'testId':
+                'ninja://:blink_web_tests/external/wpt/test/crash1.html',
+                'variant': {
+                    'def': {
+                        'test_suite': 'blink_web_tests'
+                    },
+                },
+                'status': 'CRASH',
+            }, {
+                'testId':
+                'ninja://:blink_web_tests/external/wpt/test/crash2.html',
+                'variant': {
+                    'def': {
+                        'test_suite': 'blink_web_tests'
+                    },
+                },
+                'status': 'CRASH',
+            }, {
+                'testId':
+                'ninja://:blink_web_tests/external/wpt/test/fail.html',
+                'variant': {
+                    'def': {
+                        'test_suite': 'blink_web_tests'
+                    },
+                },
+                'status': 'FAIL',
+            }] * 3)
+
+        rebaselined_tests, exp_lines = updater.update_expectations('highdpi')
+        self.assertEqual(['external/wpt/test/fail.html'], rebaselined_tests)
+        self.assertEqual(
+            {
+                'external/wpt/test/crash2.html': [
+                    'crbug.com/626703 external/wpt/test/crash2.html [ Crash ]',
+                ],
+            }, dict(exp_lines))
+        self.assertEqual(
+            host.filesystem.read_text_file(flag_exp_path).splitlines(),
+            list(
+                map(six.ensure_text, [
+                    '# results: [ Timeout Crash Pass Failure Skip ]',
+                    '',
+                    '# ====== New tests from wpt-importer added here ======',
+                    'crbug.com/626703 external/wpt/test/crash2.html [ Crash ]',
+                ])))
+        self.assertIn([
+            sys.executable,
+            '/mock-checkout/third_party/blink/tools/blink_tool.py',
+            'rebaseline-cl',
+            '--no-trigger-jobs',
+            '--fill-missing',
+            '--flag-specific=highdpi',
+            'external/wpt/test/fail.html',
+        ], host.executive.calls)
+
+    def test_cmd_arg_include_unexpected_pass_raises_exception(self):
         host = self.mock_host()
         expectations_path = \
             host.port_factory.get().path_to_generic_test_expectations_file()
@@ -496,7 +594,8 @@
         # another one has non-match results, and the last one has no
         # corresponding line in generic test expectations.
         host = self.mock_host()
-        port = host.port_factory.get()
+        updater = WPTExpectationsUpdater(host)
+        port = updater.port
 
         # Fill in an initial value for TestExpectations
         expectations_path = port.path_to_generic_test_expectations_file()
@@ -506,8 +605,6 @@
             "external/wpt/test/path.html [ Failure ]\n")
         host.filesystem.write_text_file(expectations_path, content)
 
-        updater = WPTExpectationsUpdater(host)
-
         results = {
             'external/wpt/reftest.html': {
                 tuple([DesktopConfig(port_name='one')]):
@@ -525,10 +622,8 @@
                     expected='PASS', actual='CRASH', bug='crbug.com/test'),
             }
         }
-        generic_expectations = TestExpectations(port)
-        line_dict, configs_to_remove = updater.create_line_dict_for_flag_specific(
-            results,
-            generic_expectations)
+        line_dict, configs_to_remove = updater.create_line_dict(
+            results, 'highdpi')
         self.assertEqual(
             line_dict, {
                 'external/wpt/test/path.html': [
diff --git a/third_party/blink/tools/blinkpy/web_tests/builder_list.py b/third_party/blink/tools/blinkpy/web_tests/builder_list.py
index 0394cbf..1e528a4 100644
--- a/third_party/blink/tools/blinkpy/web_tests/builder_list.py
+++ b/third_party/blink/tools/blinkpy/web_tests/builder_list.py
@@ -50,9 +50,11 @@
                 by test-results.appspot.com API."
             "has_webdriver_tests": Whether webdriver_tests_suite runs on this builder.
 
-        Possible refactoring note: Potentially, it might make sense to use
-        blinkpy.common.net.results_fetcher.Builder and add port_name and
-        specifiers properties to that class.
+        Possible refactoring note:
+            Most of these methods have `builder_name` as the first arg to look
+            into the builder registry. It might make more sense for
+            `BuilderList` to vend `Builder` named tuples with `port_name`,
+            `specifiers`, and other properties that are more ergonomic to use.
         """
         self._builders = builders_dict
         for builder in builders_dict:
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
index 2b310974..9d0de6b7 100644
--- a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
+++ b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
@@ -339,9 +339,16 @@
                 test_dict.update(
                     _interpret_test_failures(retry_result.failures))
 
+        # crbug/1328703: 'full_results.json' has become too large to upload to
+        # the test results server, so we exclude some artifacts that are not
+        # necessary for rebaselining. These artifacts are still uploaded to
+        # ResultDB.
+        skipped_artifacts = {'command', 'stderr'}
         for test_result, _ in merged_results:
             for artifact_name, artifacts in \
-                test_result.artifacts.artifacts.items():
+                    test_result.artifacts.artifacts.items():
+                if artifact_name in skipped_artifacts:
+                    continue
                 artifact_dict = test_dict.setdefault('artifacts', {})
                 artifact_dict.setdefault(artifact_name, []).extend(artifacts)
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 819d3fa..6898253 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3123,6 +3123,8 @@
 crbug.com/1223955 external/wpt/css/css-ruby/ruby-inlinize-blocks-004.html [ Failure ]
 crbug.com/1223955 external/wpt/css/css-ruby/ruby-inlinize-blocks-005.html [ Failure ]
 
+crbug.com/1333451 external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
+
 # WebRTC: Perfect Negotiation times out in Plan B. This is expected.
 crbug.com/980872 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation.https.html [ Skip Timeout ]
 
@@ -3341,7 +3343,6 @@
 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/semantics/popups/popup-light-dismiss.tentative.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11 ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
@@ -3349,13 +3350,6 @@
 crbug.com/626703 [ Mac12 ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
 crbug.com/626703 [ Mac12-arm64 ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
 crbug.com/626703 [ Win ] external/wpt/preload/preload-referrer-policy.html [ Skip Timeout ]
-crbug.com/626703 [ Linux ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Mac11 ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Mac12 ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Mac12-arm64 ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
-crbug.com/626703 [ Win ] external/wpt/css/css-ruby/intra-base-white-space-001.html [ Failure ]
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/api/basic/request-upload.h2.any.worker.html [ Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/loading/early-hints/coep-early-hints-none-final-require-corp.h2.window.html [ Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/loading/early-hints/iframe-pdf.h2.window.html [ Timeout ]
@@ -5299,7 +5293,6 @@
 crbug.com/1317079 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html [ Timeout ]
 crbug.com/1317079 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html [ Timeout ]
 crbug.com/1317079 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html [ Timeout ]
-crbug.com/1317079 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html [ Failure Timeout ]
 crbug.com/1317079 [ Linux ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Failure ]
 crbug.com/1317079 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html [ Timeout ]
 crbug.com/1223883 external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/location-set-and-document-open.html [ Timeout ]
@@ -5309,6 +5302,7 @@
 crbug.com/678633 external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html [ Failure ]
 crbug.com/1317071 [ Mac ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/1-iframe/parent-yes-child-no-port.sub.https.html [ Failure Timeout ]
 crbug.com/1323989 external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/tentative/same-document-traversal-cross-document-traversal.html [ Pass Timeout ]
+crbug.com/1197633 [ Mac11 ] external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html [ Timeout ]
 
 # Sheriff 2020-03-06
 crbug.com/1059262 virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index c5e0c396..69178771 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -2662,7 +2662,6 @@
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.worker.html [ Failure ]
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-notifications-api.any.html [ Failure ]
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-notifications-api.any.worker.html [ Failure ]
-crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html [ Timeout ]
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html [ Timeout ]
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html [ Failure ]
 crbug.com/1050754 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html [ Failure ]
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html
index 779722e..507de14 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html
@@ -13,10 +13,9 @@
 'use strict';
 
 async function customFormatWriteBeforeTest() {
-  const format = 'text/customformat';
+  const format = 'web text/customformat';
   const blob = new Blob(['CustomFormatClipboardDisabled'], {type: format});
-  const clipboardItem = new ClipboardItem(
-    {[format]: blob}, {unsanitized: [format]});
+  const clipboardItem = new ClipboardItem({[format]: blob});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItem]);
 }
@@ -32,20 +31,18 @@
   // message when the ClipboardCustomFormats flag isn't enabled.
   await customFormatWriteBeforeTest();
   const dataToWrite = 'Test text.';
-  const format = 'text/plain';
+  const format = 'web text/plain';
 
   const blobInput = new Blob([dataToWrite], {type: format});
   // Blob types are automatically converted to lower-case.
   assert_equals(blobInput.type, format.toLowerCase());
-  const clipboardItemInput = new ClipboardItem(
-      {[format]: blobInput}, {unsanitized: [format]});
+  const clipboardItemInput = new ClipboardItem({[format]: blobInput});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
 
   // Items should be readable on a system clipboard after custom format write.
   await waitForUserActivation();
-  const clipboardItems = await navigator.clipboard.read(
-    {unsanitized: [format]});
+  const clipboardItems = await navigator.clipboard.read();
   assert_equals(clipboardItems.length, 1);
   const clipboardItem = clipboardItems[0];
   assert_true(clipboardItem instanceof ClipboardItem);
@@ -55,9 +52,9 @@
   const data = await (new Response(blobOutput)).text();
   assert_equals(data, dataToWrite);
 
-  // These examples use native text formats, so these formats should be
+  // These examples use web custom text format, so this format shouldn't be
   // accessible as text.
   const textOutput = await navigator.clipboard.readText();
-  assert_equals(textOutput, dataToWrite);
-}, 'Verify write and read clipboard given custom formats as input');
+  assert_not_equals(textOutput, dataToWrite);
+}, 'Verify write and read clipboard given web custom format as input');
 </script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html
index b56095637..0f5505e1 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html
@@ -16,24 +16,18 @@
   await PermissionsHelper.setPermission('clipboard-read-write', 'granted');
   await PermissionsHelper.setPermission('clipboard-sanitized-write',
                                         'granted');
-  const format1 = 'application/x-custom-format-clipboard-test-format-1';
-  const format2 = 'application/x-custom-format-clipboard-test-format-2';
+  const format1 = 'web application/x-custom-format-clipboard-test-format-1';
+  const format2 = 'web application/x-custom-format-clipboard-test-format-2';
   const blobInput1 = new Blob(['input data 1'], {type: format1});
   const blobInput2 = new Blob(['input data 2'], {type: format2});
   const clipboardItemInput = new ClipboardItem(
-      {[format1]: blobInput1, [format2]: blobInput2},
-      {unsanitized: [format1, format2]});
+      {[format1]: blobInput1, [format2]: blobInput2});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
 
-  // Items may not be readable on the sanitized clipboard after custom format write.
-  await promise_rejects_dom(t, 'DataError',
-      navigator.clipboard.read());
-
   // Items should be readable on a custom format clipboard after custom format write.
   await waitForUserActivation();
-  const clipboardItems = await navigator.clipboard.read(
-    {unsanitized: [format1, format2]});
+  const clipboardItems = await navigator.clipboard.read();
   assert_equals(clipboardItems.length, 1);
   const clipboardItem = clipboardItems[0];
   assert_true(clipboardItem instanceof ClipboardItem);
@@ -42,12 +36,12 @@
 
   const blobOutput1 = await clipboardItem.getType(format1);
   assert_equals(blobOutput1.type, format1);
-  const data1 = await (new Response(blobOutput1)).text();
+  const data1 = await blobOutput1.text();
   assert_equals(data1, 'input data 1');
 
   const blobOutput2 = await clipboardItem.getType(format2);
   assert_equals(blobOutput2.type, format2);
-  const data2 = await (new Response(blobOutput2)).text();
+  const data2 = await blobOutput2.text();
   assert_equals(data2, 'input data 2');
 }, 'Verify write and read clipboard given 2 platform-neutral custom format inputs');
 </script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
index 02b503fd..ef2bc8cb 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
@@ -2,9 +2,13 @@
 <meta charset="utf-8">
 <title>Async Clipboard input type validation tests</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <script src="../../http/tests/resources/permissions-helper.js"></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<script src="resources/user-activation.js"></script>
 <script>
 // Permissions are required in order to invoke navigator.clipboard functions in
 // an automated test.
@@ -24,6 +28,7 @@
   const promise_blob = Promise.resolve(new Blob(['hello'], {type: 'text/plain'}));
   const item = new ClipboardItem({'text/plain': promise_blob});
 
+  await waitForUserActivation();
   await navigator.clipboard.write([item]);
 }, 'navigator.clipboard.write(Promise<Blob>) succeeds');
 
@@ -33,6 +38,7 @@
   const promise_html_blob = Promise.resolve(new Blob(["<p style='color: red; font-style: oblique;'>Test</p>"], {type: 'text/html'}));
   const item = new ClipboardItem({'text/plain': promise_text_blob, 'text/html': promise_html_blob});
 
+  await waitForUserActivation();
   await navigator.clipboard.write([item]);
 }, 'navigator.clipboard.write(Promise<Blob>s) succeeds');
 
@@ -40,6 +46,7 @@
   await getPermissions();
   const text_plain = "This text was copied using `Clipboard.prototype.write`.";
   const html_text = "<p style='color: red; font-style: oblique;'>Test</p>";
+  await waitForUserActivation();
   await promise_rejects_dom(t, "NotAllowedError", navigator.clipboard.write([
    new ClipboardItem({
             "text/plain":  text_plain,
@@ -53,6 +60,7 @@
   const blob = new Blob(['hello'], {type: 'text/plain'});
   const item = new ClipboardItem({'text/plain': blob});
 
+  await waitForUserActivation();
   await navigator.clipboard.write([item]);
 }, 'navigator.clipboard.write([text/plain ClipboardItem]) succeeds');
 
@@ -64,22 +72,26 @@
   const item1 = new ClipboardItem({'text/plain': blob1});
   const item2 = new ClipboardItem({'text/plain': blob2});
 
+  await waitForUserActivation();
   await promise_rejects_dom(t, "NotAllowedError",
       navigator.clipboard.write([item1, item2]));
 }, 'navigator.clipboard.write([>1 ClipboardItems]) fails (not implemented)');
 
 promise_test(async t => {
   await getPermissions();
+  await waitForUserActivation();
   await promise_rejects_js(t, TypeError, navigator.clipboard.write());
 }, 'navigator.clipboard.write() fails (expect [ClipboardItem])');
 
 promise_test(async t => {
   await getPermissions();
+  await waitForUserActivation();
   await promise_rejects_js(t, TypeError, navigator.clipboard.write(null));
 }, 'navigator.clipboard.write(null) fails (expect [ClipboardItem])');
 
 promise_test(async t => {
   await getPermissions();
+  await waitForUserActivation();
   await promise_rejects_js(t, TypeError,
                            navigator.clipboard.write('Bad string'));
 }, 'navigator.clipboard.write(DOMString) fails (expect [ClipboardItem])');
@@ -87,22 +99,26 @@
 promise_test(async t => {
   await getPermissions();
   const blob = new Blob(['hello'], {type: 'text/plain'});
+  await waitForUserActivation();
   await promise_rejects_js(t, TypeError, navigator.clipboard.write(blob));
 }, 'navigator.clipboard.write(Blob) fails (expect [ClipboardItem])');
 
 promise_test(async () => {
   await getPermissions();
+  await waitForUserActivation();
   await navigator.clipboard.writeText('New clipboard text');
 }, 'navigator.clipboard.writeText(DOMString) succeeds');
 
 promise_test(async t => {
   await getPermissions();
+  await waitForUserActivation();
   await promise_rejects_js(t, TypeError,
                            navigator.clipboard.writeText());
 }, 'navigator.clipboard.writeText() fails (expect DOMString)');
 
 promise_test(async () => {
   await getPermissions();
+  await waitForUserActivation();
   const result = await navigator.clipboard.read();
   assert_true(result instanceof Object);
   assert_true(result[0] instanceof ClipboardItem);
@@ -110,6 +126,7 @@
 
 promise_test(async () => {
   await getPermissions();
+  await waitForUserActivation();
   const result = await navigator.clipboard.readText();
   assert_equals(typeof result, 'string');
 }, 'navigator.clipboard.readText() succeeds');
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-garbage-collection-race-condition.html b/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-garbage-collection-race-condition.html
index 6b813db..1db5ca1 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-garbage-collection-race-condition.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-garbage-collection-race-condition.html
@@ -3,10 +3,12 @@
 <title>
   Async Clipboard write garbage collection race condition test
 </title>
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 
 <script>
 promise_test(async t => {
@@ -16,6 +18,7 @@
   const clipboardItemInput = new ClipboardItem(
         {'text/plain' : blobText});
 
+  await waitForUserActivation();
   const promise = navigator.clipboard.write([clipboardItemInput]);
   for (let i = 0; i < 10; ++i) {
     // TODO(https://github.com/web-platform-tests/wpt/issues/7899): Support
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-read-unsupported-types-removal.html b/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-read-unsupported-types-removal.html
index eb2f995..a28a0d3 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-read-unsupported-types-removal.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/clipboard-read-unsupported-types-removal.html
@@ -1,15 +1,18 @@
 <!doctype html>
 <meta charset="utf-8">
 <title>Async Clipboard read unsupported types removal test.</title>
+<body>Body needed for test_driver.click()</body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <script src="../../resources/testdriver.js"></script>
 <script src="../../resources/testdriver-vendor.js"></script>
-<body>
+<script src="resources/user-activation.js"></script>
 <script>
 'use strict';
 
 promise_test(async t => {
+  await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
+  await waitForUserActivation();
   // Write supported and unsupported types to clipboard.
   document.addEventListener('copy', event => {
     event.clipboardData.setData('text/plain', 'Supported text.');
@@ -19,7 +22,6 @@
   document.execCommand('copy');
 
   // Read clipboard contents.
-  await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
   const clipboardItems = await navigator.clipboard.read();
 
   // The unsupported unsupported-type type should be removed, leaving only
@@ -30,4 +32,3 @@
   assert_false(clipboardItem.types.includes('unsupported-type'));
 }, 'Verify that clipboard read removes unsupported types.');
 </script>
-</body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/document-transition/multiple-shared-elements-animate-crash.html b/third_party/blink/web_tests/document-transition/multiple-shared-elements-animate-crash.html
index e089ad1..f8a1fb40 100644
--- a/third_party/blink/web_tests/document-transition/multiple-shared-elements-animate-crash.html
+++ b/third_party/blink/web_tests/document-transition/multiple-shared-elements-animate-crash.html
@@ -28,18 +28,20 @@
   width: 100px;
   height: 100px;
   background: green;
+  page-transition-tag: square;
 }
 .rounded {
   width: 100px;
   height: 100px;
   background: green;
   border-radius: 20%;
+  page-transition-tag: rounded;
 }
 </style>
 
 <div id=container class=left>
-  <div id=e1 class=square></div>
-  <div id=e2 class=rounded></div>
+  <div class=square></div>
+  <div class=rounded></div>
 </div>
 
 <script>
@@ -47,8 +49,6 @@
   t.step(() => {
     requestAnimationFrame(() => requestAnimationFrame(async () => {
       let transition = document.createDocumentTransition();
-      transition.setElement(e1, "e1");
-      transition.setElement(e2, "e2");
       await transition.start(() => {
         container.classList.remove("left");
         container.classList.add("right");
diff --git a/third_party/blink/web_tests/document-transition/paint-order.html b/third_party/blink/web_tests/document-transition/paint-order.html
index 9a475000e..7e295c6 100644
--- a/third_party/blink/web_tests/document-transition/paint-order.html
+++ b/third_party/blink/web_tests/document-transition/paint-order.html
@@ -8,6 +8,7 @@
   height: 100px;
   background-color: blue;
   contain: paint;
+  page-transition-tag: shared;
 }
 html::page-transition-outgoing-image(shared) {
   opacity: 1;
@@ -33,9 +34,7 @@
   let elem = document.getElementsByTagName("div")[0];
 
   let t = document.createDocumentTransition();
-  t.setElement(elem, "shared");
   await t.start(() => {
-    t.setElement(elem, "shared");
     elem.style.backgroundColor = "red";
   });
   if (window.testRunner) {
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html
index b6c368f7..77991ec 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html
@@ -14,26 +14,19 @@
 promise_test(async t => {
   await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
-  const format1 = 'application/x-custom-format-clipboard-test-format-1';
-  const format2 = 'application/x-custom-format-clipboard-test-format-2';
+  const format1 = 'web application/x-custom-format-clipboard-test-format-1';
+  const format2 = 'web application/x-custom-format-clipboard-test-format-2';
   const blobInput1 = new Blob(['input data 1'], {type: format1});
   const blobInput2 = new Blob(['input data 2'], {type: format2});
   const clipboardItemInput = new ClipboardItem(
-      {[format1]: blobInput1, [format2]: blobInput2},
-      {unsanitized: [format1, format2]});
+      {[format1]: blobInput1, [format2]: blobInput2});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
 
-  // Items may not be readable on the sanitized clipboard after custom format
-  // write.
-  await promise_rejects_dom(t, 'DataError',
-      navigator.clipboard.read());
-
   // Items should be readable on a custom format clipboard after custom format
   // write.
   await waitForUserActivation();
-  const clipboardItems = await navigator.clipboard.read(
-    {unsanitized: [format1, format2]});
+  const clipboardItems = await navigator.clipboard.read();
   assert_equals(clipboardItems.length, 1);
   const clipboardItem = clipboardItems[0];
   assert_true(clipboardItem instanceof ClipboardItem);
@@ -58,15 +51,44 @@
   const customFormatArray = [];
   const customFormatMap = {};
   for (let i = 0; i <= 100; i++) {
-    customFormatArray.push("CustomFormat" + i);
+    customFormatArray.push("web text/CustomFormat" + i);
     const blobInput = new Blob(['input data'], {type: customFormatArray[i]});
     customFormatMap[customFormatArray[i]] = blobInput;
   }
-  const clipboardItemInput = new ClipboardItem(customFormatMap,
-      {unsanitized: customFormatArray});
+  const clipboardItemInput = new ClipboardItem(customFormatMap);
   await waitForUserActivation();
   await promise_rejects_dom(t, 'NotAllowedError',
       navigator.clipboard.write([clipboardItemInput]));
 }, 'navigator.clipboard.write() fails for more than 100 custom formats');
 
+promise_test(async t => {
+  await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
+  await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
+
+  const format1 = 'application/x-custom-format-clipboard-test-format-1';
+  const format2 = 'application/x-custom-format-clipboard-test-format-2';
+  const blobInput1 = new Blob(['input data 1'], {type: format1});
+  const blobInput2 = new Blob(['input data 2'], {type: format2});
+  const clipboardItemInput = new ClipboardItem(
+      {[format1]: blobInput1, [format2]: blobInput2});
+  await waitForUserActivation();
+  await promise_rejects_dom(t, 'NotAllowedError',
+      navigator.clipboard.write([clipboardItemInput]));
+}, 'navigator.clipboard.write() fails for custom formats without web prefix');
+
+promise_test(async t => {
+  await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
+  await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
+
+  const format1 = 'web ';
+  const format2 = 'web a';
+  const blobInput1 = new Blob(['input data 1'], {type: format1});
+  const blobInput2 = new Blob(['input data 2'], {type: format2});
+  const clipboardItemInput = new ClipboardItem(
+      {[format1]: blobInput1, [format2]: blobInput2});
+  await waitForUserActivation();
+  await promise_rejects_dom(t, 'NotAllowedError',
+      navigator.clipboard.write([clipboardItemInput]));
+}, 'navigator.clipboard.write() fails for custom formats with web prefix, but invalid MIME types');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html
index 90dc44c..44c11add 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write ([text/html ClipboardItem]) -> readHtml (and remove scripts) tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 // This function removes extra spaces between tags in html. For example, the
@@ -36,8 +38,10 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
   const blobInput = new Blob([html_with_script], {type: 'text/html'});
   const clipboardItem = new ClipboardItem({'text/html': blobInput});
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItem]);
-  const clipboardItems = await navigator.clipboard.read({type: 'text/html'});
+  await waitForUserActivation();
+  const clipboardItems = await navigator.clipboard.read();
 
   const html = clipboardItems[0];
   assert_equals(html.types.length, 1);
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html
index 5f74be1a..d1e3019 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html
@@ -7,7 +7,9 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/user-activation.js"></script>
 
+<body>Body needed for test_driver.click()
 <p><button id="button">Put payload in the clipboard</button></p>
 <div id="output"></div>
 
@@ -27,6 +29,7 @@
   await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
   await test_driver.click(button);
 
+  await waitForUserActivation();
   const items = await navigator.clipboard.read();
   const htmlBlob = await items[0].getType("text/html");
   const html = await htmlBlob.text();
@@ -38,3 +41,4 @@
   assert_false(loadObserved, 'Should not observe resource loading');
 });
 </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html
index 9e0ab2e..cc18367 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html
@@ -7,7 +7,9 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/user-activation.js"></script>
 
+<body>Body needed for test_driver.click()
 <p><button id="button">Put payload in the clipboard</button></p>
 <div id="output"></div>
 
@@ -29,6 +31,7 @@
   await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
   await test_driver.click(button);
 
+  await waitForUserActivation();
   const items = await navigator.clipboard.read();
   const htmlBlob = await items[0].getType("text/html");
   const html = await htmlBlob.text();
@@ -42,3 +45,4 @@
   assert_false(testFailed);
 });
 </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html
index e4b93c7..12184c9 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write blobs -> read blobs with promise tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 
 <script>
 async function loadBlob(fileName) {
@@ -26,8 +28,9 @@
 
   const clipboardItemInput = new ClipboardItem(
         {'text/plain' : blobText, 'image/png' : promise1});
-
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
+  await waitForUserActivation();
   const clipboardItems = await navigator.clipboard.read();
 
   assert_equals(clipboardItems.length, 1);
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-svg-script-removal.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-svg-script-removal.https.html
index cd1a551..292d100 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-svg-script-removal.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-svg-script-removal.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write ([image/svg+xml ClipboardItem]) -> readSvg (and remove scripts) tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 // This function removes extra spaces between tags in svg. For example, the
@@ -36,7 +38,9 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
   const blobInput = new Blob([svg_with_script], {type: 'image/svg+xml'});
   const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput});
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItem]);
+  await waitForUserActivation();
   const clipboardItems =
       await navigator.clipboard.read({type: 'image/svg+xml'});
 
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html
index 887ba8a..ffe6a31c 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html
@@ -32,20 +32,18 @@
 
   // Create and write unsanitized version of standard HTML and custom formats.
   const format1 = 'text/html';
-  const format2 = 'application/x-custom-format-clipboard-test-format-2';
+  const format2 = 'web text/html';
   const textInput = '<style>p {color:blue}</style><p>Hello World</p>';
-  const blobInput1 = new Blob([textInput], {type: 'text/html'});
-  const blobInput2 = new Blob(['input data 2'], {type: format2});
+  const blobInput1 = new Blob([textInput], {type: format1});
+  const blobInput2 = new Blob([textInput], {type: format2});
   const clipboardItemInput = new ClipboardItem(
-      {[format1]: blobInput1, [format2]: blobInput2},
-      {unsanitized: [format1, format2]});
+      {[format1]: blobInput1, [format2]: blobInput2});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
 
   // Read unsanitized version of HTML format.
   await waitForUserActivation();
-  const clipboardItems = await navigator.clipboard.read(
-    {unsanitized: [format1, format2]});
+  const clipboardItems = await navigator.clipboard.read();
 
   assert_equals(clipboardItems.length, 1);
   const clipboardItem = clipboardItems[0];
@@ -55,12 +53,20 @@
   assert_equals(blobOutput1.type, format1);
   const data1 = await (new Response(blobOutput1)).text();
   const outputHtml = reformatHtml(data1);
-  const inputHtml = reformatHtml(textInput);
+  const expectedHtml = '<p style="color: blue; font-size: medium; font-style: normal; ' +
+                       'font-variant-ligatures: normal; font-variant-caps: normal; ' +
+                       'font-weight: 400; letter-spacing: normal; orphans: 2; ' +
+                       'text-align: start; text-indent: 0px; text-transform: none; '+
+                       'white-space: normal; widows: 2; word-spacing: 0px; ' +
+                       '-webkit-text-stroke-width: 0px; text-decoration-thickness: initial; ' +
+                       'text-decoration-style: initial; text-decoration-color: initial;">' +
+                       'Hello World</p>';
+  const inputHtml = reformatHtml(expectedHtml);
   assert_equals(outputHtml, inputHtml);
 
   const blobOutput2 = await clipboardItem.getType(format2);
   assert_equals(blobOutput2.type, format2);
   const data2 = await (new Response(blobOutput2)).text();
-  assert_equals(data2, 'input data 2');
+  assert_equals(data2, textInput);
 }, 'Verify write and read unsanitized content to the clipboard given text/html format as input');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html
index f44ed22..1c5638ca0 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html
@@ -18,32 +18,35 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
 
   const dataToWrite = 'Test text.';
-  const format = 'text/plain';
+  const format1 = 'web text/plain';
+  const format2 = 'text/plain';
 
-  const blobInput = new Blob([dataToWrite], {type: format});
+  const blobInput1 = new Blob([dataToWrite], {type: format1});
+  const blobInput2 = new Blob([dataToWrite], {type: format2});
   // Blob types are automatically converted to lower-case.
-  assert_equals(blobInput.type, format.toLowerCase());
+  assert_equals(blobInput1.type, format1.toLowerCase());
+  assert_equals(blobInput2.type, format2.toLowerCase());
   const clipboardItemInput = new ClipboardItem(
-      {[format]: blobInput}, {unsanitized: [format]});
+      {[format1]: blobInput1, [format2]: blobInput2});
   await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
 
   // Items should be readable on a system clipboard after custom format write.
   await waitForUserActivation();
-  const clipboardItems = await navigator.clipboard.read(
-    {unsanitized: [format]});
+  const clipboardItems = await navigator.clipboard.read();
   assert_equals(clipboardItems.length, 1);
   const clipboardItem = clipboardItems[0];
   assert_true(clipboardItem instanceof ClipboardItem);
 
-  const blobOutput = await clipboardItem.getType(format);
-  assert_equals(blobOutput.type, format);
-  const data = await (new Response(blobOutput)).text();
-  assert_equals(data, dataToWrite);
+  const blobOutput1 = await clipboardItem.getType(format1);
+  assert_equals(blobOutput1.type, format1);
+  const data1 = await (new Response(blobOutput1)).text();
+  assert_equals(data1, dataToWrite);
 
   // These examples use native text formats, so these formats should be
   // accessible as text.
+  await waitForUserActivation();
   const textOutput = await navigator.clipboard.readText();
   assert_equals(textOutput, dataToWrite);
-}, 'Verify write and read unsanitized content to the clipboard given standard format as input');
+}, 'Verify write and read unsanitized content to the clipboard given standard and custom formats as input');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html
index 50d23a9c..8bec558 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write blobs -> read blobs tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 
 <script>
 async function loadBlob(fileName) {
@@ -28,7 +30,9 @@
   const clipboardItemInput = new ClipboardItem(
         {'text/plain' : blobText, 'image/png' : blobImage});
 
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
+  await waitForUserActivation();
   const clipboardItems = await navigator.clipboard.read();
 
   assert_equals(clipboardItems.length, 1);
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-html-read-html.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-html-read-html.https.html
index 7c271b9..ec1817c 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-html-read-html.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-html-read-html.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write ([text/html ClipboardItem]) -> readHtml tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 // This function removes extra spaces between tags in html. For example, the
@@ -28,7 +30,9 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
   const blobInput = new Blob([textInput], {type: 'text/html'});
   const clipboardItem = new ClipboardItem({'text/html': blobInput});
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItem]);
+  await waitForUserActivation();
   const clipboardItems = await navigator.clipboard.read({type: 'text/html'});
 
   const html = clipboardItems[0];
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image.https.html
index 281358d..e10b69d8 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image.https.html
@@ -9,6 +9,8 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/user-activation.js"></script>
+<body>Body needed for test_driver.click()
 <p>
   <p>The bottom image should display the same image as the top image.</p>
   <p>Original Image:</p>
@@ -47,7 +49,9 @@
 
   assert_equals(blobInput.type, 'image/png');
   const clipboardItemInput = new ClipboardItem({'image/png' : blobInput});
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItemInput]);
+  await waitForUserActivation();
   const clipboardItems = await navigator.clipboard.read();
 
   assert_equals(clipboardItems.length, 1);
@@ -73,7 +77,9 @@
   const invalidPngBlob = new Blob(['this text is not a valid png image'],
       {type: 'image/png'});
   const clipboardItemInput = new ClipboardItem({'image/png' : invalidPngBlob});
+  await waitForUserActivation();
   await promise_rejects_dom(t, 'DataError',
       navigator.clipboard.write([clipboardItemInput]));
 }, 'Verify write error on malformed data [image/png ClipboardItem]');
 </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html
index 19c9159..42f6c54 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write ([image/svg+xml ClipboardItem]) -> read and write svg tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 // This function removes extra spaces between tags in svg. For example, the
@@ -28,7 +30,9 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
   const blobInput = new Blob([textInput], {type: 'image/svg+xml'});
   const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput});
+  await waitForUserActivation();
   await navigator.clipboard.write([clipboardItem]);
+  await waitForUserActivation();
   const clipboardItems =
       await navigator.clipboard.read({type: 'image/svg+xml'});
 
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html
index c0f11772..b21e6b2 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html
@@ -6,6 +6,7 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<script src="../resources/user-activation.js"></script>
 <iframe id="iframe"></iframe>
 <script>
 'use strict';
@@ -21,6 +22,7 @@
   const iframeClipboard = iframe.contentWindow.navigator.clipboard;
   const blobInput = new Blob(['test string'], {type: 'text/plain'});
   const clipboardItemInput = new ClipboardItem({'text/plain': blobInput});
+  await waitForUserActivation();
   // Clipboard API must only be available in focused documents.
   // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async
   iframe.focus();
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html
index 9cd8900a..24fa586 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html
@@ -6,6 +6,7 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
+<script src="../resources/user-activation.js"></script>
 <iframe id="iframe"></iframe>
 <script>
 'use strict';
@@ -15,6 +16,7 @@
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
 
   const iframe = document.getElementById('iframe');
+  await waitForUserActivation();
   // Clipboard API must only be available in focused documents.
   // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async
   iframe.focus();
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
index 3b1cfd52..367d033d 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -17,7 +18,8 @@
 // In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome
 // only, cross-origin focus is asynchronous. Implement WPT support for
 // cross-origin focus.
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -27,4 +29,3 @@
   );
 }, 'Feature policy "clipboard-read" can be enabled in cross-origin iframe using allow="clipboard-read" attribute');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html
index 15d2684..e812854 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html
@@ -1,17 +1,19 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
 const same_origin_src =
   '/feature-policy/resources/feature-policy-clipboard-read.html';
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -21,4 +23,3 @@
   );
 }, 'Feature policy "clipboard-read" can be enabled in same-origin iframe using allow="clipboard-read" attribute');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
index 1b6f492..c371ea3b 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -17,7 +18,8 @@
 // In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome
 // only, cross-origin focus is asynchronous. Implement WPT support for
 // cross-origin focus.
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -26,4 +28,3 @@
   );
 }, 'Feature-Policy header clipboard-read "*" allows cross-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html
index f8c5bcb..552183cc6 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -15,10 +16,12 @@
 
 promise_test(async t => {
   await test_driver.set_permission({ name: 'clipboard-read' }, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.readText('test text');
 }, 'Feature-Policy header clipboard-read "*" allows the top-level document.');
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -27,4 +30,3 @@
   );
 }, 'Feature-Policy header clipboard-read "*" allows same-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
index 47aa6511..17dc362 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -15,10 +16,12 @@
 
 promise_test(async t => {
   await test_driver.set_permission({ name: 'clipboard-read' }, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.readText('test text');
 }, 'Feature-Policy header clipboard-read "self" allows the top-level document.');
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -27,7 +30,11 @@
   );
 }, 'Feature-Policy header clipboard-read "self" allows same-origin iframes.');
 
-async_test(t => {
+// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482):
+// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome
+// only, cross-origin focus is asynchronous. Implement WPT support for
+// cross-origin focus.
+promise_test(async t => {
   test_feature_availability(
     'navigator.clipboard.readText()',
     t,
@@ -36,4 +43,3 @@
   );
 }, 'Feature-Policy header clipboard-read "self" disallows cross-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
index c931bbbb..e669c8f 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -17,7 +18,8 @@
 // In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome
 // only, cross-origin focus is asynchronous. Implement WPT support for
 // cross-origin focus.
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -27,4 +29,3 @@
   );
 }, 'Feature policy "clipboard-write" can be enabled in cross-origin iframe using allow="clipboard-write" attribute');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html
index a2858c6..b57dfe3 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html
@@ -1,17 +1,19 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
 const same_origin_src =
   '/feature-policy/resources/feature-policy-clipboard-write.html';
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -21,4 +23,3 @@
   );
 }, 'Feature policy "clipboard-write" can be enabled in same-origin iframe using allow="clipboard-write" attribute');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
index 0f3164d9..6e7029c 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -17,7 +18,8 @@
 // In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome
 // only, cross-origin focus is asynchronous. Implement WPT support for
 // cross-origin focus.
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -26,4 +28,3 @@
   );
 }, 'Feature-Policy header clipboard-write "*" allows cross-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html
index 1c6fc49..ca97994c 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -15,10 +16,12 @@
 
 promise_test(async t => {
   await test_driver.set_permission({ name: 'clipboard-write' }, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.writeText('test text');
 }, 'Feature-Policy header clipboard-write "*" allows the top-level document.');
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -27,4 +30,3 @@
   );
 }, 'Feature-Policy header clipboard-write "*" allows same-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
index 51db5a4..5615a68 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html
@@ -1,10 +1,11 @@
 <!doctype html>
-<body>
+<body>Body needed for test_driver.click()</body>
 <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="/feature-policy/resources/featurepolicy.js"></script>
+<script src="../../resources/user-activation.js"></script>
 <script>
 'use strict';
 
@@ -15,10 +16,12 @@
 
 promise_test(async t => {
   await test_driver.set_permission({ name: 'clipboard-write' }, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.writeText('test text');
 }, 'Feature-Policy header clipboard-write "self" allows the top-level document.');
 
-async_test(t => {
+promise_test(async t => {
+  await waitForUserActivation();
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -27,7 +30,7 @@
   );
 }, 'Feature-Policy header clipboard-write "self" allows same-origin iframes.');
 
-async_test(t => {
+promise_test(async t => {
   test_feature_availability(
     'navigator.clipboard.writeText("test text")',
     t,
@@ -36,4 +39,3 @@
   );
 }, 'Feature-Policy header clipboard-write "self" disallows cross-origin iframes.');
 </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html
index 935f520e..010f4ba 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html
@@ -2,15 +2,18 @@
 <meta charset="utf-8">
 <title>navigator.clipboard.readText() fails when permission denied</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 
 promise_test(async t => {
   await test_driver.set_permission({name: 'clipboard-read'}, 'denied');
+  await waitForUserActivation();
   await promise_rejects_dom(t,
       'NotAllowedError', navigator.clipboard.readText());
 }, 'navigator.clipboard.readText() fails when permission denied');
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-granted.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-granted.https.html
index ab76cd5..e912bd64 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-granted.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-granted.https.html
@@ -2,15 +2,18 @@
 <meta charset="utf-8">
 <title>navigator.clipboard.readText() succeeds when permission granted</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 
 promise_test(async () => {
   await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.readText();
 }, 'navigator.clipboard.readText() succeeds when permission granted');
 </script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html
index 4d0530f..5fbcab4 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html
@@ -2,15 +2,18 @@
 <meta charset="utf-8">
 <title>navigator.clipboard.writeText() fails when permission denied</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 
 promise_test(async t => {
   await test_driver.set_permission({name: 'clipboard-write'}, 'denied');
+  await waitForUserActivation();
   await promise_rejects_dom(t, 'NotAllowedError',
       navigator.clipboard.writeText('xyz'));
 }, 'navigator.clipboard.writeText() fails when permission denied');
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-granted.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-granted.https.html
index b03ae7ff..ff347b7 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-granted.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-granted.https.html
@@ -2,15 +2,18 @@
 <meta charset="utf-8">
 <title>navigator.clipboard.writeText() succeeds when permission granted</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 'use strict';
 
 promise_test(async () => {
   await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
+  await waitForUserActivation();
   await navigator.clipboard.writeText('xyz');
 }, 'navigator.clipboard.writeText() succeeds when permission granted');
 </script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html
index a00c5b2..c46e5d4 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html
@@ -5,10 +5,12 @@
         read ([text/plain ClipboardItem]) tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
@@ -18,7 +20,9 @@
     const blobInput = new Blob([textInput], {type: 'text/plain'});
     const clipboardItemInput = new ClipboardItem({'text/plain': blobInput});
 
+    await waitForUserActivation();
     await navigator.clipboard.write([clipboardItemInput]);
+    await waitForUserActivation();
     const clipboardItems = await navigator.clipboard.read();
     assert_equals(clipboardItems.length, 1);
     const clipboardItemOutput = clipboardItems[0];
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-readText.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-readText.https.html
index e8156af..66969b1 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-readText.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-readText.https.html
@@ -4,10 +4,12 @@
   Async Clipboard write ([text/plain ClipboardItem]) -> readText tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
@@ -17,7 +19,9 @@
     const blobInput = new Blob([textInput], {type: 'text/plain'});
     const clipboardItem = new ClipboardItem({'text/plain': blobInput});
 
+    await waitForUserActivation();
     await navigator.clipboard.write([clipboardItem]);
+    await waitForUserActivation();
     const textOutput = await navigator.clipboard.readText();
 
     assert_equals(textOutput, textInput);
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-read.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-read.https.html
index 4a37aa1..ddf56326 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-read.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-read.https.html
@@ -4,17 +4,21 @@
   Async Clipboard writeText -> read ([text/plain ClipboardItem]) tests
 </title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
     await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
     await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
 
+    await waitForUserActivation();
     await navigator.clipboard.writeText(textInput);
+    await waitForUserActivation();
     const clipboardItems = await navigator.clipboard.read();
     assert_equals(clipboardItems.length, 1);
     const clipboardItem = clipboardItems[0];
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-readText.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-readText.https.html
index 7e56bfef..0defdf7 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-readText.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-writeText-readText.https.html
@@ -2,17 +2,21 @@
 <meta charset="utf-8">
 <title>Async Clipboard writeText -> readText tests</title>
 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
+<body>Body needed for test_driver.click()</body>
 <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/user-activation.js"></script>
 <script>
 async function readWriteTest(textInput) {
   promise_test(async t => {
     await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
     await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
 
+    await waitForUserActivation();
     await navigator.clipboard.writeText(textInput);
+    await waitForUserActivation();
     const textOutput = await navigator.clipboard.readText();
 
     assert_equals(textOutput, textInput);
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html
index 9fea703..0cdb8b5f 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html
@@ -9,5 +9,6 @@
 parent.postMessage({name: "domain", value: document.domain}, "*");
 parent.postMessage(
   {name: "crossOriginIsolated", value: self.crossOriginIsolated}, "*");
-parent.postMessage(new SharedArrayBuffer(10), "*");
+parent.postMessage(
+  {name: "hasSharedArrayBuffer", value: Boolean(self.SharedArrayBuffer)}, "*");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html
index 2deff50d..6fa196e 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html
@@ -5,9 +5,7 @@
 <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-
-<div id="log"></div>
-
+<body>
 <script>
 "use strict";
 document.domain = "{{host}}";
@@ -16,8 +14,8 @@
   const iframe = document.createElement("iframe");
   t.add_cleanup(() => iframe.remove());
   iframe.src = "//{{domains[www1]}}:{{location[port]}}/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html";
-  let domain = null;
-  let childCrossOriginIsolated = null;
+  let domain;
+  let childCrossOriginIsolated;
   window.onmessage = t.step_func((e) => {
     if (e.data.name === "domain") {
       domain = e.data.value;
@@ -27,16 +25,25 @@
       childCrossOriginIsolated = e.data.value;
       return;
     }
+    if (e.data.name === "hasSharedArrayBuffer") {
+      const hasSharedArrayBuffer = e.data.value;
+
+      // document.domain mutation is no-op because the surrounding agent
+      // cluster's cross-origin isolated is true.
+      assert_equals(domain, "{{domains[www1]}}");
+
+      // crossOriginIsolated is false in the nested frame because the frame is
+      // cross-origin and hence the cross-origin isolated capability is false.
+      // We use assert_equals instead of assert_false here to see if
+      // `childCrossOriginIsolated` is set.
+      assert_equals(childCrossOriginIsolated, false);
+
+      assert_false(hasSharedArrayBuffer);
+      t.done();
+      return;
+    }
     assert_unreached("Got a message event, expected a messageerror event");
   });
-  window.onmessageerror = t.step_func_done(() => {
-    // crossOriginIsolated is false in the nested frame because the frame is
-    // cross-origin and hence the cross-origin isolated capability is false.
-    assert_equals(childCrossOriginIsolated, false);
-    // But document.domain mutation is no-op because the surrounding agent
-    // cluster's cross-origin isolated is true.
-    assert_equals(domain, "{{domains[www1]}}");
-  });
   document.body.append(iframe);
 }, "SharedArrayBuffer and a same-origin-domain (but not same-origin) iframe");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/subresource-integrity.html b/third_party/blink/web_tests/external/wpt/preload/subresource-integrity.html
index 0d88aba52..58f5912 100644
--- a/third_party/blink/web_tests/external/wpt/preload/subresource-integrity.html
+++ b/third_party/blink/web_tests/external/wpt/preload/subresource-integrity.html
@@ -331,11 +331,10 @@
         {integrity: sha256}
       )
 
-      // This is an acceptable failure
       SRIPreloadTest(
         true,
         true,
-        `[Tentative] Same-origin ${destination} with matching digest does not reuse preload with matching but stronger digest.`,
+        `Same-origin ${destination} with matching digest does not reuse preload with matching but stronger digest.`,
         2,
         destination,
         same_origin_prefix + destination + ext + `?${token()}`,
@@ -345,6 +344,17 @@
 
       SRIPreloadTest(
         true,
+        false,
+        `Same-origin ${destination} with wrong digest does not reuse preload with correct and stronger digest.`,
+        2,
+        destination,
+        same_origin_prefix + destination + ext + `?${token()}`,
+        {integrity: sha384},
+        {integrity: "sha256-deadbeefQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA="}
+      )
+
+      SRIPreloadTest(
+        true,
         true,
         `Same-origin ${destination} with matching digest does not reuse preload with matching but weaker digest.`,
         2,
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/preload/subresource-integrity-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/preload/subresource-integrity-expected.txt
index f1e852a6..dbddd68 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/preload/subresource-integrity-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/preload/subresource-integrity-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 75 tests; 69 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 77 tests; 71 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Same-origin script with correct sha256 hash.
 PASS Same-origin script with correct sha384 hash.
 PASS Same-origin script with correct sha512 hash.
@@ -25,7 +25,8 @@
 PASS Same-origin script with matching digest does not re-use preload with non-matching digest.
 PASS Same-origin script with non-matching digest does not re-use preload with non-matching digest.
 PASS Same-origin script with matching digest does not reuse preload without digest.
-PASS [Tentative] Same-origin script with matching digest does not reuse preload with matching but stronger digest.
+PASS Same-origin script with matching digest does not reuse preload with matching but stronger digest.
+PASS Same-origin script with wrong digest does not reuse preload with correct and stronger digest.
 PASS Same-origin script with matching digest does not reuse preload with matching but weaker digest.
 PASS Same-origin script with non-matching digest reuses preload with no digest but fails.
 PASS Same-origin style with correct sha256 hash.
@@ -53,7 +54,8 @@
 PASS Same-origin style with matching digest does not re-use preload with non-matching digest.
 PASS Same-origin style with non-matching digest does not re-use preload with non-matching digest.
 PASS Same-origin style with matching digest does not reuse preload without digest.
-PASS [Tentative] Same-origin style with matching digest does not reuse preload with matching but stronger digest.
+PASS Same-origin style with matching digest does not reuse preload with matching but stronger digest.
+PASS Same-origin style with wrong digest does not reuse preload with correct and stronger digest.
 PASS Same-origin style with matching digest does not reuse preload with matching but weaker digest.
 PASS Same-origin style with non-matching digest reuses preload with no digest but fails.
 PASS Same-origin image with correct sha256 hash.
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-max-texture-size.html b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-max-texture-size.html
index a5d994ca..de2f2d8c 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-max-texture-size.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-max-texture-size.html
@@ -31,7 +31,9 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
+#target1 { page-transition-tag: target1; }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
 html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
@@ -56,14 +58,7 @@
   scrollblue.scrollIntoView();
 
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-
-  t.setElement(target1, "target1");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-
-    t.setElement(target1, "target1");
-
     requestAnimationFrame(() => requestAnimationFrame(() => 
       requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
     ));
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-root.html b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-root.html
index 33b500b..fa57a3b 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-root.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip-root.html
@@ -26,6 +26,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 body {
@@ -63,14 +64,10 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-
   t.start(() => {
-    t.setElement(hidden, "hidden");
-
     // Add a shared element to ensure its bounds don't expand the root snapshot
     // size.
-    t.setElement(target2, "target2");
+    target2.style = "page-transition-tag: target2";
 
     requestAnimationFrame(() => requestAnimationFrame(() => 
       requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip.html b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip.html
index 9d2ac25..da8b916 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-clip.html
@@ -26,6 +26,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 /* Makes sure the viewport height is consistent for scrollbars to align */
@@ -45,7 +46,7 @@
 
 </style>
 
-<div id="target1" class="target">
+<div id="target1" class="target" style="page-transition-tag: target1">
   <div class="embedded" style="background: green;"></div>
   <div class="embedded" style="background: blue"></div>
 </div>
@@ -58,14 +59,9 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-
-  t.setElement(target1, "target1");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-
-    t.setElement(target2, "target2");
-
+    target1.style = "";
+    target2.style = "page-transition-tag: target2";
     requestAnimationFrame(() => requestAnimationFrame(() => 
       requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
     ));
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-new-image.html b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-new-image.html
index 6d506b99..3540360 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-new-image.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-new-image.html
@@ -12,6 +12,7 @@
   width: 100px;
   height: 100px;
   transform: scale(2.0, 3.0);
+  page-transition-tag: target;
 }
 
 .embedded {
@@ -24,6 +25,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
@@ -46,12 +48,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "target");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-    t.setElement(target, "target");
-
     requestAnimationFrame(() =>  requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-old-image.html b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-old-image.html
index e1090d4..c0b9bef 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-old-image.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/content-with-transform-old-image.html
@@ -12,6 +12,7 @@
   width: 100px;
   height: 100px;
   transform: scale(2.0, 3.0);
+  page-transition-tag: target;
 }
 
 .embedded {
@@ -24,6 +25,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
@@ -46,12 +48,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "target");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-    t.setElement(target, "target");
-
     requestAnimationFrame(() =>  requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/duplicate_tag_rejects.html b/third_party/blink/web_tests/wpt_internal/document-transition/duplicate_tag_rejects.html
index 1e9eb2ca..67bfabf 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/duplicate_tag_rejects.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/duplicate_tag_rejects.html
@@ -23,17 +23,8 @@
 promise_test(async t => {
   return new Promise((resolve, reject) => {
     let transition = document.createDocumentTransition();
-    transition.setElement(first, "target");
-    transition.setElement(first, "target");
-    transition.start(()=>{}).then(resolve, reject);
-  });
-}, "Same element with the same tag is no-op");
-
-promise_test(async t => {
-  return new Promise((resolve, reject) => {
-    let transition = document.createDocumentTransition();
-    transition.setElement(first, "target");
-    transition.setElement(second, "target");
+    first.style = "page-transition-tag: target";
+    second.style = "page-transition-tag: target";
     transition.start(()=>{}).then(reject, resolve);
   });
 }, "Two different elements with the same tag rejects capture");
@@ -41,10 +32,10 @@
 promise_test(async t => {
   return new Promise((resolve, reject) => {
     let transition = document.createDocumentTransition();
-    transition.setElement(first, "target");
+    first.style = "page-transition-tag: target";
     transition.start(() => {
-      transition.setElement(first, "target");
-      transition.setElement(second, "target");
+      first.style = "page-transition-tag: target";
+      second.style = "page-transition-tag: target";
     }).then(reject, resolve);
   });
 }, "Two different elements with the same tag rejects start");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-clip-path.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-clip-path.html
index 9cd4722..46226b0 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-clip-path.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-clip-path.html
@@ -19,6 +19,7 @@
   clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
   top: 20px;
   left: 20px;
+  page-transition-tag: e1;
 }
 
 div.dst { background: lightgreen; }
@@ -35,9 +36,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
   t.start(() => {
-    t.setElement(e1, "e1");
     e1.classList.add("dst");
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-different-size.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-different-size.html
index 60090ec4..6e48c65 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-different-size.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-different-size.html
@@ -19,16 +19,19 @@
   clip-path: circle(30%);
   top: 20px;
   left: 20px;
+  page-transition-tag: e1;
 }
 #e2 {
   clip-path: ellipse(70% 30%);
   top: 160px;
   left: 20px;
+  page-transition-tag: e2;
 }
 #e3 {
   filter: blur(5px);
   top: 300px;
   left: 20px;
+  page-transition-tag: e3;
 }
 
 div.dst { background: lightgreen; }
@@ -46,13 +49,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
-  t.setElement(e2, "e2");
-  t.setElement(e3, "e3");
   t.start(() => {
-    t.setElement(e1, "e1");
-    t.setElement(e2, "e2");
-    t.setElement(e3, "e3");
     e1.classList.add("dst");
     e2.classList.add("dst");
     e3.classList.add("dst");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
index 6120466..0232d624 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
@@ -16,9 +16,9 @@
   font-size: 30pt;
   will-change: opacity;
 }
-#e1 { opacity: 0.75; top: 20px; left: 20px; }
-#e2 { opacity: 0.5; top: 160px; left: 20px; }
-#e3 { opacity: 0.25; top: 300px; left: 20px; }
+#e1 { opacity: 0.75; top: 20px; left: 20px; page-transition-tag: e1; }
+#e2 { opacity: 0.5; top: 160px; left: 20px; page-transition-tag: e2; }
+#e3 { opacity: 0.25; top: 300px; left: 20px; page-transition-tag: e3; }
 div.dst { background: lightgreen; }
 /* We're verifying what we capture, so just display the new contents for 5 minutes.  */
 html::page-transition-container(*) { animation-duration: 300s; }
@@ -34,13 +34,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
-  t.setElement(e2, "e2");
-  t.setElement(e3, "e3");
   t.start(() => {
-    t.setElement(e1, "e1");
-    t.setElement(e2, "e2");
-    t.setElement(e3, "e3");
     e1.classList.add("dst");
     e2.classList.add("dst");
     e3.classList.add("dst");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-root.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-root.html
index af415fc..36b15fb 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-root.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-root.html
@@ -23,6 +23,7 @@
   width: 100px;
   height: 100px;
   background: red;
+  page-transition-tag: shared;
 }
 
 div.dst { background: lightgreen; }
@@ -38,9 +39,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(shared, "shared");
   t.start(() => {
-    t.setElement(shared, "shared");
     e1.classList.add("dst");
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-container-writing-modes.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-container-writing-modes.html
index 0d52055..6417da9 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-container-writing-modes.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-container-writing-modes.html
@@ -14,6 +14,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .tb { writing-mode: horizontal-tb; }
 .lr { writing-mode: vertical-lr; }
@@ -26,7 +27,7 @@
   contain: paint;
   border: 1px solid black;
 }
-#target {
+.source {
   background: red;
   position: absolute;
   top: 50px;
@@ -35,7 +36,6 @@
   height: 500px;
   contain: paint;
 }
-
 html::page-transition-container(hidden) { animation-duration: 300s; }
 html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
 
@@ -58,7 +58,9 @@
 </style>
 
 <div id=hidden>Should not be visible</div>
-<div id=target>Should not be visible</div>
+<div id=s1 class=source>Should not be visible</div>
+<div id=s2 class=source>Should not be visible</div>
+<div id=s3 class=source>Should not be visible</div>
 <div class=tb><div id=one class=shared>T</div></div>
 <div class=lr><div id=two class=shared>T</div></div>
 <div class=rl><div id=three class=shared>T</div></div>
@@ -66,17 +68,17 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "s1");
-  t.setElement(target, "s2");
-  t.setElement(target, "s3");
+  s1.style = "page-transition-tag: s1";
+  s2.style = "page-transition-tag: s2";
+  s3.style = "page-transition-tag: s3";
   t.start(() => {
-    target.remove();
-    t.setElement(hidden, "hidden");
+    s1.remove();
+    s2.remove();
+    s3.remove();
     hidden.style.left = "200px";
-    t.setElement(one, "s1");
-    t.setElement(two, "s2");
-    t.setElement(three, "s3");
+    one.style = "page-transition-tag: s1";
+    two.style = "page-transition-tag: s2";
+    three.style = "page-transition-tag: s3";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-element-writing-modes.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-element-writing-modes.html
index 99408fab..3905d6d 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-element-writing-modes.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-element-writing-modes.html
@@ -14,6 +14,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .tb { writing-mode: horizontal-tb; }
 .lr { writing-mode: vertical-lr; }
@@ -58,7 +59,9 @@
 </style>
 
 <div id=hidden>Should not be visible</div>
-<div id=target>Should not be visible</div>
+<div id=s1 class=source>Should not be visible</div>
+<div id=s2 class=source>Should not be visible</div>
+<div id=s3 class=source>Should not be visible</div>
 <div id=one class="tb shared">T</div>
 <div id=two class="lr shared">T</div>
 <div id=three class="rl shared">T</div>
@@ -66,17 +69,17 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "s1");
-  t.setElement(target, "s2");
-  t.setElement(target, "s3");
+  s1.style = "page-transition-tag: s1";
+  s2.style = "page-transition-tag: s2";
+  s3.style = "page-transition-tag: s3";
   t.start(() => {
-    target.remove();
-    t.setElement(hidden, "hidden");
+    s1.remove();
+    s2.remove();
+    s3.remove();
     hidden.style.left = "200px";
-    t.setElement(one, "s1");
-    t.setElement(two, "s2");
-    t.setElement(three, "s3");
+    one.style = "page-transition-tag: s1";
+    two.style = "page-transition-tag: s2";
+    three.style = "page-transition-tag: s3";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-is-empty-div.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-is-empty-div.html
index 047a504..ce94d81 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-is-empty-div.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-is-empty-div.html
@@ -47,9 +47,10 @@
 <script>
 async function runTest() {
   const t = document.createDocumentTransition();
-  t.setElement(source, "shared");
+  source.style = "page-transition-tag: shared";
   t.start(() => {
-    t.setElement(target, "shared");
+    source.style = "";
+    target.style = "page-transition-tag: shared";
 
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-element-on-start.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-element-on-start.html
index 6981ea8..c0e98eb 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-element-on-start.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-element-on-start.html
@@ -54,11 +54,12 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(before, "before");
+  hidden.style.pageTransitionTag = "hidden";
+  before.style.pageTransitionTag = "before";
   t.start(() => {
     before.remove();
-    t.setElement(after, "after");
+    hidden.style.pageTransitionTag = "";
+    after.style.pageTransitionTag = "after";
 
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-root-vertical-writing-mode.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-root-vertical-writing-mode.html
index bab4a23..cd9d75d 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-root-vertical-writing-mode.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-root-vertical-writing-mode.html
@@ -15,6 +15,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .shared {
   margin: 2px;
@@ -31,6 +32,7 @@
   width: 100px;
   height: 500px;
   contain: paint;
+  page-transition-tag: s1;
 }
 #two {
   background: lightblue;
@@ -56,13 +58,10 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "s1");
   t.start(() => {
     target.remove();
-    t.setElement(hidden, "hidden");
     hidden.style.left = "200px";
-    t.setElement(one, "s1");
+    one.style.pageTransitionTag = "s1";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-new-image.html b/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-new-image.html
index 5b5c72e..db766e6a 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-new-image.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-new-image.html
@@ -15,6 +15,7 @@
   position: relative;
   top: 200px;
   left: 200px;
+  page-transition-tag: target;
 }
 
 .embedded {
@@ -27,6 +28,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
@@ -58,12 +60,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "target");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-    t.setElement(target, "target");
-
     requestAnimationFrame(() =>  requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-old-image.html b/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-old-image.html
index 9d47347..0666714 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-old-image.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/object-view-box-old-image.html
@@ -15,6 +15,7 @@
   position: relative;
   top: 200px;
   left: 200px;
+  page-transition-tag: target;
 }
 
 .embedded {
@@ -27,6 +28,7 @@
   width: 10px;
   height: 10px;
   background: grey;
+  page-transition-tag: hidden;
 }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
@@ -58,12 +60,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(target, "target");
   t.start(() => {
-    t.setElement(hidden, "hidden");
-    t.setElement(target, "target");
-
     requestAnimationFrame(() =>  requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-clip-path.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-clip-path.html
index 0cc9535..d9e81355 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-clip-path.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-clip-path.html
@@ -19,6 +19,7 @@
   clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
   top: 20px;
   left: 20px;
+  page-transition-tag: e1;
 }
 
 div.dst { background: lightgreen; }
@@ -34,9 +35,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
   t.start(() => {
-    t.setElement(e1, "e1");
     e1.classList.add("dst");
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-different-size.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-different-size.html
index 830b497..30d835e 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-different-size.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-different-size.html
@@ -19,16 +19,19 @@
   clip-path: circle(30%);
   top: 20px;
   left: 20px;
+  page-transition-tag: e1;
 }
 #e2 {
   clip-path: ellipse(70% 30%);
   top: 160px;
   left: 20px;
+  page-transition-tag: e2;
 }
 #e3 {
   filter: blur(5px);
   top: 300px;
   left: 20px;
+  page-transition-tag: e3;
 }
 
 div.dst { background: lightgreen; }
@@ -46,13 +49,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
-  t.setElement(e2, "e2");
-  t.setElement(e3, "e3");
   t.start(() => {
-    t.setElement(e1, "e1");
-    t.setElement(e2, "e2");
-    t.setElement(e3, "e3");
     e1.classList.add("dst");
     e2.classList.add("dst");
     e3.classList.add("dst");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-opacity.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-opacity.html
index 7e2b225..204af0f 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-opacity.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-opacity.html
@@ -17,9 +17,9 @@
   position: absolute;
   font-size: 30pt;
 }
-#e1 { opacity: 0.75; top: 20px; left: 20px; }
-#e2 { opacity: 0.5; top: 160px; left: 20px; }
-#e3 { opacity: 0.25; top: 300px; left: 20px; }
+#e1 { opacity: 0.75; top: 20px; left: 20px; page-transition-tag: e1; }
+#e2 { opacity: 0.5; top: 160px; left: 20px; page-transition-tag: e2; }
+#e3 { opacity: 0.25; top: 300px; left: 20px; page-transition-tag: e3; }
 div.dst { background: lightgreen; }
 /* We're verifying what we capture, so just display the old contents for 5 minutes.  */
 html::page-transition-container(*) { animation-duration: 300s; }
@@ -35,13 +35,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
-  t.setElement(e2, "e2");
-  t.setElement(e3, "e3");
   t.start(() => {
-    t.setElement(e1, "e1");
-    t.setElement(e2, "e2");
-    t.setElement(e3, "e3");
     e1.classList.add("dst");
     e2.classList.add("dst");
     e3.classList.add("dst");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-root.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-root.html
index 6a7d1de..389e1d31 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-root.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-captures-root.html
@@ -23,6 +23,7 @@
   width: 100px;
   height: 100px;
   background: red;
+  page-transition-tag: shared;
 }
 
 div.dst { background: lightgreen; }
@@ -38,9 +39,7 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(shared, "shared");
   t.start(() => {
-    t.setElement(shared, "shared");
     e1.classList.add("dst");
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-container-writing-modes.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-container-writing-modes.html
index 2a1be16..ae05fe8 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-container-writing-modes.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-container-writing-modes.html
@@ -14,6 +14,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .tb { writing-mode: horizontal-tb; }
 .lr { writing-mode: vertical-lr; }
@@ -26,7 +27,7 @@
   contain: paint;
   border: 1px solid black;
 }
-#target {
+#target1, #target2, #target3 {
   background: red;
   position: absolute;
   top: 50px;
@@ -35,6 +36,9 @@
   height: 500px;
   contain: paint;
 }
+#one { page-transition-tag: s1; }
+#two { page-transition-tag: s2; }
+#three { page-transition-tag: s3; }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
 html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
@@ -61,7 +65,9 @@
 </style>
 
 <div id=hidden>Should not be visible</div>
-<div id=target>Should not be visible</div>
+<div id=target1>Should not be visible</div>
+<div id=target2>Should not be visible</div>
+<div id=target3>Should not be visible</div>
 <div class=tb><div id=one class=shared>T</div></div>
 <div class=lr><div id=two class=shared>T</div></div>
 <div class=rl><div id=three class=shared>T</div></div>
@@ -69,19 +75,14 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(one, "s1");
-  t.setElement(two, "s2");
-  t.setElement(three, "s3");
   t.start(() => {
     one.remove();
     two.remove();
     three.remove();
-    t.setElement(hidden, "hidden");
     hidden.style.left = "200px";
-    t.setElement(target, "s1");
-    t.setElement(target, "s2");
-    t.setElement(target, "s3");
+    target1.style.pageTransitionTag = "s1";
+    target2.style.pageTransitionTag = "s2";
+    target3.style.pageTransitionTag = "s3";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-element-writing-modes.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-element-writing-modes.html
index c37a171..662d8d9 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-element-writing-modes.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-element-writing-modes.html
@@ -14,6 +14,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .tb { writing-mode: horizontal-tb; }
 .lr { writing-mode: vertical-lr; }
@@ -26,7 +27,7 @@
   contain: paint;
   border: 1px solid black;
 }
-#target {
+#target1, #target2, #target3 {
   background: red;
   position: absolute;
   top: 50px;
@@ -35,6 +36,9 @@
   height: 500px;
   contain: paint;
 }
+#one { page-transition-tag: s1; }
+#two { page-transition-tag: s2; }
+#three { page-transition-tag: s3; }
 
 html::page-transition-container(hidden) { animation-duration: 300s; }
 html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
@@ -61,7 +65,9 @@
 </style>
 
 <div id=hidden>Should not be visible</div>
-<div id=target>Should not be visible</div>
+<div id=target1>Should not be visible</div>
+<div id=target2>Should not be visible</div>
+<div id=target3>Should not be visible</div>
 <div id=one class="shared tb">T</div>
 <div id=two class="shared lr">T</div>
 <div id=three class="shared rl">T</div>
@@ -69,19 +75,14 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(one, "s1");
-  t.setElement(two, "s2");
-  t.setElement(three, "s3");
   t.start(() => {
     one.remove();
     two.remove();
     three.remove();
-    t.setElement(hidden, "hidden");
     hidden.style.left = "200px";
-    t.setElement(target, "s1");
-    t.setElement(target, "s2");
-    t.setElement(target, "s3");
+    target1.style.pageTransitionTag = "s1";
+    target2.style.pageTransitionTag = "s2";
+    target3.style.pageTransitionTag = "s3";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-is-empty-div.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-is-empty-div.html
index e694cd3..1043dc0 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-content-is-empty-div.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-content-is-empty-div.html
@@ -47,9 +47,10 @@
 <script>
 async function runTest() {
   const t = document.createDocumentTransition();
-  t.setElement(empty, "shared");
+  empty.style.pageTransitionTag = "shared";
   t.start(() => {
-    t.setElement(target, "shared");
+    empty.style.pageTransitionTag = "";
+    target.style.pageTransitionTag = "shared";
 
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/old-root-vertical-writing-mode.html b/third_party/blink/web_tests/wpt_internal/document-transition/old-root-vertical-writing-mode.html
index 1130307..6469e9b 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/old-root-vertical-writing-mode.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/old-root-vertical-writing-mode.html
@@ -15,6 +15,7 @@
   top: 0;
   left: 0;
   contain: paint;
+  page-transition-tag: hidden;
 }
 .shared {
   margin: 2px;
@@ -32,6 +33,7 @@
   height: 500px;
   contain: paint;
 }
+#one { page-transition-tag: s1; }
 #two {
   background: lightblue;
   will-change: transform;
@@ -57,13 +59,10 @@
 <script>
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(one, "s1");
   t.start(() => {
     one.remove();
     target.style = "";
-    t.setElement(hidden, "hidden");
-    t.setElement(target, "s1");
+    target.style.pageTransitionTag = "s1";
     hidden.style.left = "200px";
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets-ref.html
deleted file mode 100644
index f4d5906e..0000000
--- a/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets-ref.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<title>Shared transitions: one element captured for two tags (ref)</title>
-<link rel="help" href="https://github.com/WICG/shared-element-transitions">
-<link rel="author" href="mailto:vmpstr@chromium.org">
-<style>
-.result {
-  background: green;
-  width: 100px;
-  height: 100px;
-  contain: paint;
-  position: absolute;
-  top: 50px;
-}
-.result.one {
-  left: 50px;
-}
-.result.two {
-  left: 200px;
-}
-body { background: lightpink; }
-</style>
-<div class="result one"></div>
-<div class="result two"></div>
-
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets.html b/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets.html
deleted file mode 100644
index 628e5382..0000000
--- a/third_party/blink/web_tests/wpt_internal/document-transition/one-element-two-targets.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!DOCTYPE html>
-<html class=reftest-wait>
-<title>Shared transitions: one element captured for two tags</title>
-<link rel="help" href="https://github.com/WICG/shared-element-transitions">
-<link rel="author" href="mailto:vmpstr@chromium.org">
-<link rel="match" href="one-element-two-targets-ref.html">
-
-<script src="/common/reftest-wait.js"></script>
-<style>
-div { contain: paint; }
-.source {
-  background: green;
-  width: 100px;
-  height: 100px;
-}
-.hidden {
-  background: pink;
-  width: 10px;
-  height: 10px;
-  page-transition-tag: hidden;
-}
-.target {
-  width: 100px;
-  height: 100px;
-  position: absolute;
-  top: 50px;
-  background: red;
-}
-.target.one {
-  left: 50px;
-}
-.target.two {
-  left: 200px;
-}
-
-
-html::page-transition-container(hidden) { animation-duration: 300s; }
-html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
-
-html::page-transition-container(target1) { animation-duration: 0s; }
-html::page-transition-incoming-image(target1) { animation: unset; opacity: 0; }
-html::page-transition-outgoing-image(target1) { animation: unset; opacity: 1; }
-
-html::page-transition-container(target2) { animation-duration: 0s; }
-html::page-transition-incoming-image(target2) { animation: unset; opacity: 0; }
-html::page-transition-outgoing-image(target2) { animation: unset; opacity: 1; }
-
-html::page-transition-container(root) { animation: unset; opacity: 0; }
-html::page-transition { background: lightpink; }
-
-</style>
-
-<div id=from class=source></div>
-<div id=left class="target one"></div>
-<div id=right class="target two"></div>
-
-<div id=hidden class=hidden></div>
-
-<script>
-async function runTest() {
-  let t = document.createDocumentTransition();
-  t.setElement(from, "target1");
-  t.setElement(from, "target2");
-  t.start(() => {
-    t.setElement(left, "target1");
-    t.setElement(right, "target2");
-
-    requestAnimationFrame(() => requestAnimationFrame(() => 
-      requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
-    ));
-  });
-}
-onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
-</script>
-
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/reserved_root_tag_rejects.html b/third_party/blink/web_tests/wpt_internal/document-transition/reserved_root_tag_rejects.html
deleted file mode 100644
index bfa3f13..0000000
--- a/third_party/blink/web_tests/wpt_internal/document-transition/reserved_root_tag_rejects.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html class=reftest-wait>
-<title>Shared transitions: root tag is reserved</title>
-<link rel="help" href="https://github.com/WICG/shared-element-transitions">
-<link rel="author" href="mailto:vmpstr@chromium.org">
-
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-
-<style>
-#target {
-  width: 100px;
-  height: 100px;
-  background: blue;
-  contain: paint;
-}
-</style>
-
-<div id=target></div>
-
-<script>
-promise_test(async t => {
-  return new Promise((resolve, reject) => {
-    let transition = document.createDocumentTransition();
-    transition.setElement(target, "root");
-    transition.start().then(reject, resolve);
-  });
-}, "Root tag on an element rejects capture");
-
-promise_test(async t => {
-  return new Promise((resolve, reject) => {
-    let transition = document.createDocumentTransition();
-    transition.setElement(target, "foo");
-    transition.start(() => {
-      transition.setElement(target, null);
-      transition.setElement(target, "root");
-    }).then(reject, resolve);
-  });
-}, "Root tag on an element rejects start");
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/root-scrollbar-with-fixed-background.html b/third_party/blink/web_tests/wpt_internal/document-transition/root-scrollbar-with-fixed-background.html
index 2f331d0..6de9ba27 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/root-scrollbar-with-fixed-background.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/root-scrollbar-with-fixed-background.html
@@ -17,6 +17,7 @@
   height: 10px;
   background: red;
   contain: paint;
+  page-transition-tag: hide;
 }
 #first {
   width: 10px;
@@ -54,9 +55,7 @@
 
   document.documentElement.scrollTop = 500;
   let t = document.createDocumentTransition();
-  t.setElement(hide, "hide");
   t.start(() => {
-    t.setElement(hide, "hide");
     requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
   });
 }
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-author-style.manual.html b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-author-style.manual.html
index bbd1b50b8..b9e967e 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-author-style.manual.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-author-style.manual.html
@@ -76,7 +76,7 @@
 
 async function runAnimation() {
   let t = document.createDocumentTransition();
-  t.setElement(target, "target");
+  target.style.pageTransitionTag = "target";
   await t.start(() => {
     target.classList.remove(classes[i]);
     i = (i + 1) % classes.length;
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-half.manual.html b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-half.manual.html
index 4a45e55..a2e1791 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-half.manual.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-half.manual.html
@@ -45,7 +45,7 @@
 let i = 0;
 async function runAnimation() {
   let t = document.createDocumentTransition();
-  t.setElement(target, "target");
+  target.style.pageTransitionTag = "target";
   await t.start(() => {
     target.classList.remove(classes[i]);
     i = (i + 1) % classes.length;
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-shapes.manual.html b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-shapes.manual.html
index 9963eefe..277e2f00 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-shapes.manual.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/shared-transition-shapes.manual.html
@@ -61,11 +61,11 @@
 let i = 0;
 async function runAnimation() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
-  t.setElement(e2, "e2");
-  t.setElement(e3, "e3");
-  t.setElement(e4, "e4");
-  t.setElement(e5, "e5");
+  e1.style.pageTransitionTag = "e1";
+  e2.style.pageTransitionTag = "e2";
+  e3.style.pageTransitionTag = "e3";
+  e4.style.pageTransitionTag = "e4";
+  e5.style.pageTransitionTag = "e5";
   await t.start(() => {
     container.classList.remove(classes[i]);
     i = (i + 1) % classes.length;
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/transition-waits-for-animations.html b/third_party/blink/web_tests/wpt_internal/document-transition/transition-waits-for-animations.html
index 9da3cc84..0f53118a 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/transition-waits-for-animations.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/transition-waits-for-animations.html
@@ -28,6 +28,7 @@
   height: 100px;
   background: green;
 }
+#e1 { page-transition-tag: e1; }
 </style>
 
 <div id=e1 class="square left"></div>
@@ -35,7 +36,6 @@
 <script>
 async function startTransition() {
   let t = document.createDocumentTransition();
-  t.setElement(e1, "e1");
   t.start(() => {
     e1.classList.remove("left");
     e1.classList.add("right");
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target-ref.html
deleted file mode 100644
index 21cf96a..0000000
--- a/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target-ref.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<title>Shared transitions: one element captured for two tags (ref)</title>
-<link rel="help" href="https://github.com/WICG/shared-element-transitions">
-<link rel="author" href="mailto:vmpstr@chromium.org">
-<style>
-.result {
-  width: 100px;
-  height: 100px;
-  contain: paint;
-  opacity: 0.5;
-  position: absolute;
-  top: 10px;
-  left: 10px;
-}
-.result.one {
-  background: green;
-  z-index: 1;
-}
-.result.two {
-  background: blue;
-}
-body { background: lightpink; }
-</style>
-<div style="isolation: isolate">
-  <div class="result one"></div>
-  <div class="result two"></div>
-</div>
-
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target.html b/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target.html
deleted file mode 100644
index f66084f..0000000
--- a/third_party/blink/web_tests/wpt_internal/document-transition/two-elements-one-target.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!DOCTYPE html>
-<html class=reftest-wait>
-<title>Shared transitions: one element captured for two tags</title>
-<link rel="help" href="https://github.com/WICG/shared-element-transitions">
-<link rel="author" href="mailto:vmpstr@chromium.org">
-<link rel="match" href="two-elements-one-target-ref.html">
-
-<script src="/common/reftest-wait.js"></script>
-<style>
-div { contain: paint; }
-.source {
-  width: 100px;
-  height: 100px;
-  opacity: 0.5;
-  position: absolute;
-  top: 50px;
-}
-.source.one {
-  left: 50px;
-  background: green;
-}
-.source.two {
-  left: 200px;
-  background: blue;
-}
-.hidden {
-  background: pink;
-  width: 10px;
-  height: 10px;
-}
-.target {
-  width: 100px;
-  height: 100px;
-  background: red;
-  position: absolute;
-  top: 10px;
-  left: 10px;
-}
-
-
-html::page-transition-container(hidden) { animation-duration: 300s; }
-html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
-
-html::page-transition-container(target1) { z-index: 1; animation-duration: 0s; }
-html::page-transition-incoming-image(target1) { animation: unset; opacity: 0; }
-html::page-transition-outgoing-image(target1) { animation: unset; opacity: 1; }
-
-html::page-transition-container(target2) { animation-duration: 0s; }
-html::page-transition-incoming-image(target2) { animation: unset; opacity: 0; }
-html::page-transition-outgoing-image(target2) { animation: unset; opacity: 1; }
-
-html::page-transition-container(root) { animation: unset; opacity: 0; }
-html::page-transition { background: lightpink; }
-
-</style>
-
-<div id=to class=target></div>
-<div id=left class="source one"></div>
-<div id=right class="source two"></div>
-
-<div id=hidden class=hidden></div>
-
-<script>
-async function runTest() {
-  let t = document.createDocumentTransition();
-  t.setElement(hidden, "hidden");
-  t.setElement(left, "target1");
-  t.setElement(right, "target2");
-  t.start(() => {
-    t.setElement(to, "target1");
-    t.setElement(to, "target2");
-
-    requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
-  });
-}
-onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
-</script>
-
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/uncontained-transition-crash.html b/third_party/blink/web_tests/wpt_internal/document-transition/uncontained-transition-crash.html
index b6fef28..25df7ed7 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/uncontained-transition-crash.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/uncontained-transition-crash.html
@@ -32,9 +32,10 @@
   await waitForAtLeastOneFrame();
   // Prepare with a shared element
   let t = document.createDocumentTransition();
-  t.setElement(first, "shared");
+  first.style.pageTransitionTag = "shared";
   let promise = t.start(() => {
-    t.setElement(second, "shared");
+    first.style.pageTransitionTag = "";
+    second.style.pageTransitionTag = "shared";
   });
 
   // The start() call above starts the capture. Force a hit test, which will
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/web-animations-api.html b/third_party/blink/web_tests/wpt_internal/document-transition/web-animations-api.html
index 2eceaa6..7015f70 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/web-animations-api.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/web-animations-api.html
@@ -39,9 +39,10 @@
 
 async function runTest() {
   let t = document.createDocumentTransition();
-  t.setElement(document.getElementById("first"), "first");
+  first.style.pageTransitionTag = "first";
   t.start(() => {
-    t.setElement(document.getElementById("second"), "second");
+    first.style.pageTransitionTag = "";
+    second.style.pageTransitionTag = "second";
     requestAnimationFrame(setAnimation);
   });
 }
diff --git a/tools/json_to_struct/PRESUBMIT.py b/tools/json_to_struct/PRESUBMIT.py
index e94c1f8..13895f0 100644
--- a/tools/json_to_struct/PRESUBMIT.py
+++ b/tools/json_to_struct/PRESUBMIT.py
@@ -18,7 +18,7 @@
       output_api,
       '.',
       files_to_check=ALLOWEDLIST,
-      skip_shebang_check=True)
+      run_on_python2=False)
 
 
 def CheckChangeOnCommit(input_api, output_api):
@@ -27,4 +27,4 @@
       output_api,
       '.',
       files_to_check=ALLOWEDLIST,
-      skip_shebang_check=True)
+      run_on_python2=False)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 6cfaf9f..494e2d0 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -282,7 +282,7 @@
       'ASan Release Media (32-bit x86 with V8-ARM)': 'asan_fuzzer_v8_heap_chromeos_codecs_release_bot_hybrid_reclient',
       'Afl Upload Linux ASan': 'afl_asan_shared_release_bot_reclient',
       'ChromiumOS ASAN Release': 'chromeos_asan_lsan_fuzzer_v8_heap_release_bot_reclient',
-      'Libfuzzer Upload Chrome OS ASan': 'libfuzzer_chromeos_asan_release_bot',
+      'Libfuzzer Upload Chrome OS ASan': 'libfuzzer_chromeos_asan_release_bot_reclient',
       'Libfuzzer Upload Linux ASan': 'libfuzzer_asan_release_bot_reclient',
       'Libfuzzer Upload Linux ASan Debug': 'libfuzzer_asan_debug_bot_reclient',
       'Libfuzzer Upload Linux MSan': 'libfuzzer_msan_release_bot_reclient',
@@ -2897,6 +2897,10 @@
       'libfuzzer', 'asan', 'shared_release_bot', 'chromeos_with_codecs', 'pdf_xfa', 'disable_nacl', 'optimize_for_fuzzing', 'disable_seed_corpus',
     ],
 
+    'libfuzzer_chromeos_asan_release_bot_reclient': [
+      'libfuzzer', 'asan', 'shared_release_bot_reclient', 'chromeos_with_codecs', 'pdf_xfa', 'disable_nacl', 'optimize_for_fuzzing', 'disable_seed_corpus',
+    ],
+
     'libfuzzer_mac_asan_shared_release_bot': [
       'libfuzzer', 'asan', 'shared_release_bot', 'chrome_with_codecs', 'pdf_xfa', 'disable_nacl', 'optimize_for_fuzzing',
     ],
diff --git a/tools/mb/mb_config_expectations/chromium.fuzz.json b/tools/mb/mb_config_expectations/chromium.fuzz.json
index 13b2980..b271ea1d 100644
--- a/tools/mb/mb_config_expectations/chromium.fuzz.json
+++ b/tools/mb/mb_config_expectations/chromium.fuzz.json
@@ -127,8 +127,9 @@
       "pdf_enable_xfa": true,
       "proprietary_codecs": true,
       "target_os": "chromeos",
-      "use_goma": true,
-      "use_libfuzzer": true
+      "use_libfuzzer": true,
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Libfuzzer Upload Linux ASan": {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index a2c7a18..dcad7e7 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -6292,6 +6292,26 @@
   </description>
 </action>
 
+<action name="ContentSuggestions.Follow.FirstFollow.GotItButtonTapped">
+  <owner>adamta@google.org</owner>
+  <owner>feed@chromium.org</owner>
+  <owner>sczs@chromium.org</owner>
+  <owner>tinazwang@chromium.org</owner>
+  <description>
+    The user tapped Got It button on the first follow sheet. iOS only.
+  </description>
+</action>
+
+<action name="ContentSuggestions.Follow.FirstFollow.GoToFeedButtonTapped">
+  <owner>adamta@google.org</owner>
+  <owner>feed@chromium.org</owner>
+  <owner>sczs@chromium.org</owner>
+  <owner>tinazwang@chromium.org</owner>
+  <description>
+    The user tapped Go To Feed button on the first follow sheet. iOS only.
+  </description>
+</action>
+
 <action name="ContentSuggestions.Follow.SnackbarGoToFeedButtonTapped">
   <owner>adamta@google.org</owner>
   <owner>sczs@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ab0c335..ba52e8e 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -40760,13 +40760,12 @@
   <int value="40"
       label="User tapped Settings link to open feed autoplay settings."/>
   <int value="41"
-      label="User tapped &quot;Add to Reading List&quot; in the context menu."/>
+      label="User tapped 'Add to Reading List' in the context menu."/>
   <int value="42"
       label="User tapped the Manage icon to visit the feed management
              interstitial."/>
   <int value="43"
-      label="User tapped &quot;Hidden&quot; in the feed management
-             interstitial."/>
+      label="User tapped 'Hidden' in the feed management interstitial."/>
   <int value="44"
       label="User tapped the Follow button on the page overflow menu."/>
   <int value="45"
@@ -40782,6 +40781,12 @@
   <int value="52"
       label="User tapped to go to feed using the snackbar 'go to feed'
              option."/>
+  <int value="53" label="User tapped the Crow button in the context menu"/>
+  <int value="54" label="Show First Follow Sheet"/>
+  <int value="55"
+      label="User tapped the 'Go To Feed' button on the first follow sheet."/>
+  <int value="56"
+      label="User tapped the 'Got It' button on the first follow sheet."/>
 </enum>
 
 <enum name="FeedUserCommandType">
@@ -56194,6 +56199,7 @@
   <int value="-1151615978" label="BorealisBigGl:disabled"/>
   <int value="-1151476162" label="LacrosMergeIcuDataFile:disabled"/>
   <int value="-1151014496" label="NearbySharingDeviceContacts:disabled"/>
+  <int value="-1149544733" label="OffsetparentNewSpecBehavior:enabled"/>
   <int value="-1146814438" label="TabbedAppOverflowMenuIcons:enabled"/>
   <int value="-1146310028" label="HardwareSecureDecryptionFallback:enabled"/>
   <int value="-1145905507" label="SendTabToSelfWhenSignedIn:disabled"/>
@@ -57765,6 +57771,7 @@
   <int value="-92116820" label="InlineUpdateFlow:enabled"/>
   <int value="-91767554" label="enable-de-jelly"/>
   <int value="-91370149" label="UseSerialBusEnumerator:enabled"/>
+  <int value="-90799024" label="OffsetparentNewSpecBehavior:disabled"/>
   <int value="-90521375" label="PDFTwoUpView:enabled"/>
   <int value="-90032223" label="BuiltInModuleInfra:disabled"/>
   <int value="-89690053" label="MaterialDesignUserManager:enabled"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 028270b4..84263ae 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -215,6 +215,22 @@
   <token key="Theme" variants="AmbientModeThemes"/>
 </histogram>
 
+<histogram name="Ash.AmbientMode.PhotoOrientationMatch.{Theme}" units="%"
+    expires_after="2022-12-01">
+  <owner>esum@google.com</owner>
+  <owner>xiaohuic@chromium.org</owner>
+  <summary>
+    Applies to ambient mode animations with image assets embedded in them (spots
+    in the animation where the user's photos should be plugged in). Captures the
+    percentage of time that the orientation (landscape vs portrait) of the image
+    asset matches that of the actual photo being assigned to it. Ideally this is
+    100%. Does not apply to the slideshow ambient theme. Emitted each time the
+    photos in the animation are refreshed (after each animation cycle is
+    complete).
+  </summary>
+  <token key="Theme" variants="AmbientModeThemes"/>
+</histogram>
+
 <histogram name="Ash.AmbientMode.PhotoSource" enum="AmbientModePhotoSource"
     expires_after="2022-12-01">
   <owner>cowmoo@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/oobe/histograms.xml b/tools/metrics/histograms/metadata/oobe/histograms.xml
index 5cb70b6f..1d67b5d8 100644
--- a/tools/metrics/histograms/metadata/oobe/histograms.xml
+++ b/tools/metrics/histograms/metadata/oobe/histograms.xml
@@ -180,18 +180,6 @@
   </summary>
 </histogram>
 
-<histogram name="OOBE.HidDetectionScreen.HidDisconnected" enum="HidType"
-    expires_after="2023-05-06">
-  <owner>gordonseto@google.com</owner>
-  <owner>cros-connectivity@google.com</owner>
-  <summary>
-    Records the type of a connected human interface device (HID) that is
-    disconnected. This metric is emitted each time a HID is disconnected during
-    the HID detection screen in OOBE. It does not include devices disconnected
-    before the screen is shown or after the screen is hidden.
-  </summary>
-</histogram>
-
 <histogram name="OOBE.MarketingOptInScreen.BackendConnector"
     enum="MarketingOptInBackendConnectorEvent" expires_after="2022-11-30">
   <owner>rrsilva@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index f8afcc3f..a90e897 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -11835,73 +11835,70 @@
   </summary>
 </histogram>
 
-<histogram name="Shutdown.browser_exit.time2" units="units" expires_after="M81">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.BrowserExit.Time" units="ms" expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
     Time for shutdown initiated by the browser exit menu command.
   </summary>
 </histogram>
 
-<histogram name="Shutdown.browser_exit.time_per_process" units="units"
-    expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
-  <summary>
-    Time for shutdown initiated by the browser exit menu command per renderer
-    process.
-  </summary>
-</histogram>
-
-<histogram name="Shutdown.end_session.time2" units="units" expires_after="M78">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.EndSession.Time" units="ms" expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
     Time for shutdown initiated by an end session (user logs off, shuts down or
     reboots without explicitly exiting).
   </summary>
 </histogram>
 
-<histogram name="Shutdown.end_session.time_per_process" units="units"
-    expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.NotValid.Time" units="ms" expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
-    Time for shutdown initiated by an end session (user logs off, shuts down or
-    reboots without explicitly exiting) per renderer process.
+    Time for shutdown for a not valid exit. This situation happen when a chrome
+    process is already running and the process is terminated after the process
+    singleton rendez-vous.
   </summary>
 </histogram>
 
-<histogram name="Shutdown.renderers.slow" units="units" expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.Renderers.Slow" units="renderers"
+    expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
     The number of renderer processes that couldn't be shutdown quickly due to
     onbeforeunload or onunload listeners.
   </summary>
 </histogram>
 
-<histogram name="Shutdown.renderers.total" units="units" expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.Renderers.Total" units="renderers"
+    expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
     The number of renderer processes running when shutdown was called.
   </summary>
 </histogram>
 
 <histogram name="Shutdown.ShutdownType" enum="ShutdownType"
-    expires_after="2020-04-19">
-  <owner>hashimoto@chromium.org</owner>
+    expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>The type of the last shutdown.</summary>
 </histogram>
 
-<histogram name="Shutdown.window_close.time2" units="ms" expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
-  <summary>
-    Time for shutdown initiated by the last browser window being closed.
-  </summary>
+<histogram name="Shutdown.SilentExit.Time" units="ms" expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
+  <summary>Time for shutdown for a silent exit.</summary>
 </histogram>
 
-<histogram name="Shutdown.window_close.time_per_process" units="units"
-    expires_after="M77">
-  <owner>hashimoto@chromium.org</owner>
+<histogram name="Shutdown.WindowClose.Time" units="ms" expires_after="M107">
+  <owner>etienneb@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
-    Time for shutdown initiated by the last browser window being closed per
-    renderer process.
+    Time for shutdown initiated by the last browser window being closed.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/scheduler/histograms.xml b/tools/metrics/histograms/metadata/scheduler/histograms.xml
index 47f1636..047c16d4 100644
--- a/tools/metrics/histograms/metadata/scheduler/histograms.xml
+++ b/tools/metrics/histograms/metadata/scheduler/histograms.xml
@@ -138,20 +138,6 @@
   </summary>
 </histogram>
 
-<histogram name="Scheduler.TaskQueueImpl.PostDelayedTaskDelay" units="ms"
-    expires_after="2022-09-30">
-  <owner>yafroze@google.com</owner>
-  <owner>pmonette@chromium.org</owner>
-  <owner>catan-team@chromium.org</owner>
-  <summary>
-    The delay time for the delayed tasks posted to the sequence manager.
-
-    A sample is chosen pseudorandomly when PostDelayedTask is enqueuing tasks.
-
-    Note: This metric merges from all named threads.
-  </summary>
-</histogram>
-
 <histogram name="Scheduling.BeginImplFrameLatency2" units="microseconds"
     expires_after="M85">
   <owner>stanisc@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index 7fba727..62b22a3 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -221,16 +221,6 @@
   </summary>
 </histogram>
 
-<histogram name="ServiceWorker.CookieChangeEvent.Time" units="ms"
-    expires_after="M85">
-  <owner>pwnall@chromium.org</owner>
-  <summary>
-    The time taken between dispatching a CookieChangeEvent to a Service Worker
-    and receiving a message that it finished handling the event. Includes the
-    time for the waitUntil() promise to settle.
-  </summary>
-</histogram>
-
 <histogram name="ServiceWorker.Database.DestroyDatabaseResult"
     enum="ServiceWorkerDatabaseStatus" expires_after="2022-10-11">
   <owner>bashi@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 3f4cfce..31b49010 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "5917c2f13de8a1616fce4f6641e653825fa95852",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/d836f02e9ab596cc817bff3efcae6287f9ee0403/trace_processor_shell.exe"
+            "hash": "4defee27b67daefdfe066497b82e6b2314ba6bca",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/03b8dd28776e2302fc80953b5df0d0d4424f670c/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
@@ -14,7 +14,7 @@
         },
         "mac": {
             "hash": "f8def2233b28bf40d61363174b172594e2dd375e",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/d836f02e9ab596cc817bff3efcae6287f9ee0403/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/6e4908679c0e807b51186ab313f7fade72335aba/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "7eb4e73a87f9132b1cabb5601579867f4d72bb41",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/d836f02e9ab596cc817bff3efcae6287f9ee0403/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6e4908679c0e807b51186ab313f7fade72335aba/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
index d68cf0b..72cacd18 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "11.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "12.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
index 1236cbb..c1b5eed 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "9.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "10.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel4-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel4-perf_timing.json
index b080648..0a5e5ca 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel4-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel4-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "7.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "8.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel4_webview-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel4_webview-perf_timing.json
index dd32c63..faf48c6 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel4_webview-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel4_webview-perf_timing.json
@@ -1117,10 +1117,6 @@
     },
     {
         "duration": "7.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
-        "duration": "7.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
diff --git a/tools/perf/core/shard_maps/timing_data/lacros-eve-perf_timing.json b/tools/perf/core/shard_maps/timing_data/lacros-eve-perf_timing.json
index 58fef1e9..2884af1 100644
--- a/tools/perf/core/shard_maps/timing_data/lacros-eve-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/lacros-eve-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "61.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "58.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/linux-perf_timing.json b/tools/perf/core/shard_maps/timing_data/linux-perf_timing.json
index de2f140..7b6283c 100644
--- a/tools/perf/core/shard_maps/timing_data/linux-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/linux-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "3.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "8.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json b/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
index 7762aa6..7c8af74 100644
--- a/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
@@ -1117,10 +1117,6 @@
     },
     {
         "duration": "4.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
-        "duration": "4.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
diff --git a/tools/perf/core/shard_maps/timing_data/mac-laptop_low_end-perf_timing.json b/tools/perf/core/shard_maps/timing_data/mac-laptop_low_end-perf_timing.json
index 258bbf9..e20353d 100644
--- a/tools/perf/core/shard_maps/timing_data/mac-laptop_low_end-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/mac-laptop_low_end-perf_timing.json
@@ -1157,10 +1157,6 @@
     },
     {
         "duration": "6.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
-        "duration": "6.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
diff --git a/tools/perf/core/shard_maps/timing_data/mac-m1_mini_2020-perf_timing.json b/tools/perf/core/shard_maps/timing_data/mac-m1_mini_2020-perf_timing.json
index fb95269..9acc55c 100644
--- a/tools/perf/core/shard_maps/timing_data/mac-m1_mini_2020-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/mac-m1_mini_2020-perf_timing.json
@@ -1117,10 +1117,6 @@
     },
     {
         "duration": "3.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
-        "duration": "3.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
diff --git a/tools/perf/core/shard_maps/timing_data/win-10-perf_timing.json b/tools/perf/core/shard_maps/timing_data/win-10-perf_timing.json
index a131f95..18fce06 100644
--- a/tools/perf/core/shard_maps/timing_data/win-10-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/win-10-perf_timing.json
@@ -1117,10 +1117,6 @@
     },
     {
         "duration": "6.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
-        "duration": "6.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
diff --git a/tools/perf/core/shard_maps/timing_data/win-10_laptop_low_end-perf_timing.json b/tools/perf/core/shard_maps/timing_data/win-10_laptop_low_end-perf_timing.json
index f3b7a36b..63f121c 100644
--- a/tools/perf/core/shard_maps/timing_data/win-10_laptop_low_end-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/win-10_laptop_low_end-perf_timing.json
@@ -1116,10 +1116,6 @@
         "name": "blink_perf.parser/declarative-shadow-dom.html"
     },
     {
-        "duration": "7.0",
-        "name": "blink_perf.parser/html-parser-threaded.html"
-    },
-    {
         "duration": "8.0",
         "name": "blink_perf.parser/html-parser.html"
     },
diff --git a/tools/variations/fieldtrial_to_struct.py b/tools/variations/fieldtrial_to_struct.py
index 9ecf3897..3c90ff9 100755
--- a/tools/variations/fieldtrial_to_struct.py
+++ b/tools/variations/fieldtrial_to_struct.py
@@ -76,7 +76,7 @@
 def _ConvertOverrideUIStrings(override_ui_strings):
   """Converts override_ui_strings to formatted dicts."""
   overrides = []
-  for ui_string, override in override_ui_strings.iteritems():
+  for ui_string, override in override_ui_strings.items():
     overrides.append({
         'name_hash': generate_ui_string_overrider.HashName(ui_string),
         'value': override
diff --git a/tools/variations/fieldtrial_util.py b/tools/variations/fieldtrial_util.py
index ac0b9f5..284bcb5 100644
--- a/tools/variations/fieldtrial_util.py
+++ b/tools/variations/fieldtrial_util.py
@@ -31,7 +31,7 @@
       duplicates.add(entry)
     else:
       seen.add(entry)
-  return duplicates
+  return sorted(duplicates)
 
 def _CheckForDuplicateFeatures(enable_features, disable_features):
   enable_features = [f.split('<')[0] for f in enable_features]
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 19e74f8..c0d082d 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4449,7 +4449,88 @@
 IFACEMETHODIMP
 AXPlatformNodeWin::get_selections(IA2TextSelection** selections,
                                   LONG* nSelections) {
-  return E_NOTIMPL;
+  COM_OBJECT_VALIDATE_2_ARGS(selections, nSelections);
+
+  AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
+
+  AXTree::Selection unignored_selection =
+      GetDelegate()->GetUnignoredSelection();
+
+  AXNodeID anchor_id = unignored_selection.anchor_object_id;
+  AXPlatformNodeWin* anchor_node =
+      static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(anchor_id));
+  if (!anchor_node)
+    return E_FAIL;
+
+  // If the selection endpoint is inside this object and therefore, at least
+  // from this side, we do not need to crop the selection. Simply convert
+  // selection anchor/focus offset to a hypertext offset within anchor/focus
+  // object. Otherwise per the IA2 Spec, we need to crop the selection to be
+  // within this object. `AXPlatformNodeBase::GetHypertextOffsetFromEndpoint`
+  // can correctly handle endpoint offsets that are outside this object by
+  // returning either 0 or hypertext length; see the related comment in
+  // the method's declaration.
+
+  int anchor_offset = unignored_selection.anchor_offset;
+  if (anchor_node->IsDescendant(this)) {
+    anchor_offset =
+        anchor_node->GetHypertextOffsetFromEndpoint(anchor_node, anchor_offset);
+  } else {
+    anchor_offset = GetHypertextOffsetFromEndpoint(anchor_node, anchor_offset);
+    anchor_node = this;
+  }
+  DCHECK_GE(anchor_offset, 0)
+      << "This value is unexpected here, since we have already determined in "
+         "this method that anchor_object is in the accessibility tree.";
+
+  AXNodeID focus_id = unignored_selection.focus_object_id;
+  AXPlatformNodeWin* focus_node =
+      static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(focus_id));
+  if (!focus_node)
+    return E_FAIL;
+
+  int focus_offset = unignored_selection.focus_offset;
+  if (focus_node->IsDescendant(this)) {
+    focus_offset =
+        focus_node->GetHypertextOffsetFromEndpoint(focus_node, focus_offset);
+  } else {
+    focus_offset = GetHypertextOffsetFromEndpoint(focus_node, focus_offset);
+    focus_node = this;
+  }
+  DCHECK_GE(focus_offset, 0)
+      << "This value is unexpected here, since we have already determined in "
+         "this method that focus_object is in the accessibility tree.";
+
+  if (anchor_node == focus_node && anchor_offset == focus_offset)
+    return S_FALSE;  // No selection within this subtree.
+
+  Microsoft::WRL::ComPtr<IAccessibleText> anchor_text_node;
+  if (FAILED(anchor_node->QueryInterface(IID_PPV_ARGS(&anchor_text_node))))
+    return E_FAIL;
+
+  Microsoft::WRL::ComPtr<IAccessibleText> focus_text_node;
+  if (FAILED(focus_node->QueryInterface(IID_PPV_ARGS(&focus_text_node))))
+    return E_FAIL;
+
+  *selections = reinterpret_cast<IA2TextSelection*>(
+      CoTaskMemAlloc(sizeof(IA2TextSelection)));
+
+  if (unignored_selection.is_backward) {
+    selections[0]->startObj = focus_text_node.Detach();
+    selections[0]->startOffset = focus_offset;
+    selections[0]->endObj = anchor_text_node.Detach();
+    selections[0]->endOffset = anchor_offset;
+    selections[0]->startIsActive = true;
+  } else {
+    selections[0]->startObj = anchor_text_node.Detach();
+    selections[0]->startOffset = anchor_offset;
+    selections[0]->endObj = focus_text_node.Detach();
+    selections[0]->endOffset = focus_offset;
+    selections[0]->startIsActive = false;
+  }
+
+  *nSelections = 1;
+  return S_OK;
 }
 
 IFACEMETHODIMP AXPlatformNodeWin::setSelections(LONG nSelections,
diff --git a/ui/base/clipboard/clipboard.cc b/ui/base/clipboard/clipboard.cc
index c4a0cbc..4a840e9 100644
--- a/ui/base/clipboard/clipboard.cc
+++ b/ui/base/clipboard/clipboard.cc
@@ -14,9 +14,12 @@
 #include "base/memory/ptr_util.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
+#include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "net/base/mime_util.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/clipboard/clipboard_constants.h"
 #include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
 
@@ -151,8 +154,20 @@
       if (json_val.has_value()) {
         for (const auto it : json_val->DictItems()) {
           const std::string* custom_format_name = it.second.GetIfString();
-          if (custom_format_name)
-            custom_format_names.emplace(it.first, *custom_format_name);
+          if (custom_format_name) {
+            // Prepend "web " prefix to the custom format.
+            std::string web_top_level_mime_type;
+            std::string web_mime_sub_type;
+            std::string web_format = it.first;
+            if (net::ParseMimeTypeWithoutParameter(
+                    web_format, &web_top_level_mime_type, &web_mime_sub_type)) {
+              std::string web_custom_format_string = base::StrCat(
+                  {kWebClipboardFormatPrefix, web_top_level_mime_type, "/",
+                   web_mime_sub_type});
+              custom_format_names.emplace(std::move(web_custom_format_string),
+                                          *custom_format_name);
+            }
+          }
         }
       }
     }
diff --git a/ui/base/clipboard/clipboard_constants.cc b/ui/base/clipboard/clipboard_constants.cc
index cfc684bd..fec0f3c 100644
--- a/ui/base/clipboard/clipboard_constants.cc
+++ b/ui/base/clipboard/clipboard_constants.cc
@@ -47,5 +47,6 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
 const int kMaxRegisteredClipboardFormats = 100;
+const char kWebClipboardFormatPrefix[] = "web ";
 
 }  // namespace ui
diff --git a/ui/base/clipboard/clipboard_constants.h b/ui/base/clipboard/clipboard_constants.h
index bd36747..6d52a0f1 100644
--- a/ui/base/clipboard/clipboard_constants.h
+++ b/ui/base/clipboard/clipboard_constants.h
@@ -97,6 +97,10 @@
 COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
 extern const int kMaxRegisteredClipboardFormats;
 
+// Web prefix for web custom format types.
+COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
+extern const char kWebClipboardFormatPrefix[];
+
 }  // namespace ui
 
 #endif  // UI_BASE_CLIPBOARD_CLIPBOARD_CONSTANTS_H_
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index ac0b16ea..410ecbeb 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -721,7 +721,7 @@
 // TODO(crbug.com/106449): Implement multiple custom format write on Chrome OS.
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 TYPED_TEST(ClipboardTest, DataTest) {
-  const std::string kFormatString = "chromium/x-test-format";
+  const std::string kFormatString = "web chromium/x-test-format";
   const std::u16string kFormatString16 = u"chromium/x-test-format";
   const std::string payload = "test string";
   base::span<const uint8_t> payload_span(
@@ -747,13 +747,13 @@
 }
 
 TYPED_TEST(ClipboardTest, MultipleDataTest) {
-  const std::string kFormatString1 = "chromium/x-test-format1";
+  const std::string kFormatString1 = "web chromium/x-test-format1";
   const std::u16string kFormatString116 = u"chromium/x-test-format1";
   const std::string payload1("test string1");
   base::span<const uint8_t> payload_span1(
       reinterpret_cast<const uint8_t*>(payload1.data()), payload1.size());
 
-  const std::string kFormatString2 = "chromium/x-test-format2";
+  const std::string kFormatString2 = "web chromium/x-test-format2";
   const std::u16string kFormatString216 = u"chromium/x-test-format2";
   const std::string payload2("test string2");
   base::span<const uint8_t> payload_span2(
@@ -771,7 +771,7 @@
   // Check format 1.
   EXPECT_THAT(this->clipboard().ReadAvailableStandardAndCustomFormatNames(
                   ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr),
-              Contains(kFormatString116));
+              Contains(u"web chromium/x-test-format1"));
   std::string custom_format_json;
   this->clipboard().ReadData(ClipboardFormatType::WebCustomFormatMap(),
                              /* data_dst = */ nullptr, &custom_format_json);
@@ -789,7 +789,7 @@
   // Check format 2.
   EXPECT_THAT(this->clipboard().ReadAvailableStandardAndCustomFormatNames(
                   ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr),
-              Contains(kFormatString216));
+              Contains(u"web chromium/x-test-format2"));
   EXPECT_TRUE(custom_format_names.find(kFormatString2) !=
               custom_format_names.end());
   std::string output2;
@@ -800,13 +800,13 @@
 }
 
 TYPED_TEST(ClipboardTest, DataAndPortableFormatTest) {
-  const std::string kFormatString1 = "chromium/x-test-format1";
+  const std::string kFormatString1 = "web chromium/x-test-format1";
   const std::u16string kFormatString116 = u"chromium/x-test-format1";
   const std::string payload1("test string1");
   base::span<const uint8_t> payload_span1(
       reinterpret_cast<const uint8_t*>(payload1.data()), payload1.size());
 
-  const std::string kFormatString2 = "text/plain";
+  const std::string kFormatString2 = "web text/plain";
   const std::u16string kFormatString216 = u"text/plain";
   const std::string payload2("test string2");
   base::span<const uint8_t> payload_span2(
@@ -824,7 +824,7 @@
   // Check format 1.
   EXPECT_THAT(this->clipboard().ReadAvailableStandardAndCustomFormatNames(
                   ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr),
-              Contains(kFormatString116));
+              Contains(u"web chromium/x-test-format1"));
   std::string custom_format_json;
   this->clipboard().ReadData(ClipboardFormatType::WebCustomFormatMap(),
                              /* data_dst = */ nullptr, &custom_format_json);
@@ -842,7 +842,7 @@
   // Check format 2.
   EXPECT_THAT(this->clipboard().ReadAvailableStandardAndCustomFormatNames(
                   ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr),
-              Contains(kFormatString216));
+              Contains(u"web text/plain"));
   EXPECT_TRUE(custom_format_names.find(kFormatString2) !=
               custom_format_names.end());
   std::string output2;
@@ -868,7 +868,8 @@
     return;
 
   const std::string text = "test string";
-  const std::string kFormatString = "text/plain";
+  const std::string kFormatString = "web text/plain";
+  const std::u16string kFormatString16 = u"text/plain";
 #if BUILDFLAG(IS_WIN)
   // Windows requires an extra '\0' at the end for a raw write.
   const std::string kPlatformSpecificText = text + '\0';
@@ -880,7 +881,7 @@
       kPlatformSpecificText.size());
   {
     ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste);
-    clipboard_writer.WriteData(ASCIIToUTF16(kFormatString),
+    clipboard_writer.WriteData(kFormatString16,
                                mojo_base::BigBuffer(text_span));
   }
 
diff --git a/ui/color/color_provider_manager.h b/ui/color/color_provider_manager.h
index c5d1deb5..03556fc3 100644
--- a/ui/color/color_provider_manager.h
+++ b/ui/color/color_provider_manager.h
@@ -110,15 +110,13 @@
     base::WeakPtr<InitializerSupplier> app_controller;
 
     bool operator<(const Key& other) const {
-      const auto lhs =
-          std::make_tuple(color_mode, contrast_mode, elevation_mode,
-                          system_theme, frame_type, custom_theme);
-      const auto rhs = std::make_tuple(other.color_mode, other.contrast_mode,
-                                       other.elevation_mode, other.system_theme,
-                                       other.frame_type, other.custom_theme);
-      if (lhs == rhs)
-        return app_controller.get() < other.app_controller.get();
-      return lhs < rhs;
+      auto* lhs_app_controller = app_controller.get();
+      auto* rhs_app_controller = other.app_controller.get();
+      return std::tie(color_mode, contrast_mode, elevation_mode, system_theme,
+                      frame_type, custom_theme, lhs_app_controller) <
+             std::tie(other.color_mode, other.contrast_mode,
+                      other.elevation_mode, other.system_theme,
+                      other.frame_type, other.custom_theme, rhs_app_controller);
     }
   };
 
diff --git a/ui/gl/angle_platform_impl.h b/ui/gl/angle_platform_impl.h
index 0bbbabb5..5eabd6c 100644
--- a/ui/gl/angle_platform_impl.h
+++ b/ui/gl/angle_platform_impl.h
@@ -8,9 +8,10 @@
 // Implements the ANGLE platform interface, for functionality like
 // histograms and trace profiling.
 
-#include "ui/gl/gl_context_egl.h"
 #include "ui/gl/gl_export.h"
 
+typedef void* EGLDisplay;
+
 namespace angle {
 
 GL_EXPORT bool InitializePlatform(EGLDisplay display);
diff --git a/ui/gl/egl_api_unittest.cc b/ui/gl/egl_api_unittest.cc
index d6b8588..37e9790 100644
--- a/ui/gl/egl_api_unittest.cc
+++ b/ui/gl/egl_api_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_egl_api_implementation.h"
 #include "ui/gl/gl_surface_egl.h"
 #include "ui/gl/gl_switches.h"
@@ -50,10 +51,10 @@
     if (disabled_extensions) {
       SetDisabledExtensionsEGL(disabled_extensions);
     }
-    g_driver_egl.InitializeClientExtensionBindings();
+    g_driver_egl.ext.InitializeClientExtensionSettings();
     display_ = GLSurfaceEGL::InitializeDisplay(
         EGLDisplayPlatform(EGL_DEFAULT_DISPLAY), /*system_device_id=*/0);
-    g_driver_egl.InitializeExtensionBindings();
+    g_driver_egl.ext.InitializeExtensionSettings(display_);
   }
 
   void SetFakeExtensionString(const char* fake_string,
@@ -109,7 +110,7 @@
   static const char* fake_extension_string_;
   static const char* fake_client_extension_string_;
 
-  GLDisplay* display_ = nullptr;
+  GLDisplayEGL* display_ = nullptr;
   std::unique_ptr<RealEGLApi> api_;
 };
 
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index fff5586..b9760e9 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -2791,6 +2791,46 @@
   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' },
 ]
 
+# EGL client extensions that may not add a function but are still queried.
+EGL_CLIENT_EXTENSIONS_EXTRA = [
+  'EGL_ANGLE_display_power_preference',
+  'EGL_ANGLE_platform_angle',
+  'EGL_ANGLE_platform_angle_d3d',
+  'EGL_ANGLE_platform_angle_device_id',
+  'EGL_ANGLE_platform_angle_device_type_egl_angle',
+  'EGL_ANGLE_platform_angle_device_type_swiftshader',
+  'EGL_ANGLE_platform_angle_metal',
+  'EGL_ANGLE_platform_angle_null',
+  'EGL_ANGLE_platform_angle_opengl',
+  'EGL_ANGLE_platform_angle_vulkan',
+  'EGL_EXT_platform_device',
+  'EGL_MESA_platform_surfaceless',
+]
+
+# EGL extensions that may not add a function but are still queried.
+EGL_EXTENSIONS_EXTRA = [
+  'EGL_ANDROID_create_native_client_buffer',
+  'EGL_ANDROID_front_buffer_auto_refresh',
+  'EGL_ANGLE_display_semaphore_share_group',
+  'EGL_ANGLE_display_texture_share_group',
+  'EGL_ANGLE_context_virtualization',
+  'EGL_ANGLE_create_context_client_arrays',
+  'EGL_ANGLE_create_context_webgl_compatibility',
+  'EGL_ANGLE_external_context_and_surface',
+  'EGL_ANGLE_surface_orientation',
+  'EGL_ANGLE_window_fixed_size',
+  'EGL_CHROMIUM_create_context_bind_generates_resource',
+  'EGL_EXT_create_context_robustness',
+  'EGL_EXT_gl_colorspace_display_p3',
+  'EGL_EXT_gl_colorspace_display_p3_passthrough',
+  'EGL_EXT_pixel_format_float',
+  'EGL_IMG_context_priority',
+  'EGL_KHR_gl_colorspace',
+  'EGL_KHR_no_config_context',
+  'EGL_KHR_surfaceless_context',
+  'EGL_NV_robustness_video_memory_purge',
+]
+
 GLX_FUNCTIONS = [
 { 'return_type': 'void',
   'names': ['glXBindTexImageEXT'],
@@ -3075,9 +3115,11 @@
 namespace gl {
 
 class GLContext;
-
 """ % {'name': set_name.upper()})
 
+  if set_name == 'egl':
+    file.write("class GLDisplayEGL;\n")
+
   # Write typedefs for function pointer types. Always use the GL name for the
   # typedef.
   file.write('\n')
@@ -3087,11 +3129,27 @@
 
   # Write declarations for booleans indicating which extensions are available.
   file.write('\n')
-  file.write("struct Extensions%s {\n" % set_name.upper())
+  if set_name == 'egl':
+    file.write('struct GL_EXPORT ExtensionsEGL {\n')
+  else:
+    file.write("struct Extensions%s {\n" % set_name.upper())
   for extension in sorted(used_client_extensions):
     file.write('  bool b_%s;\n' % extension)
   for extension in sorted(used_extensions):
     file.write('  bool b_%s;\n' % extension)
+  if set_name == 'egl':
+    file.write(
+"""
+
+  void InitializeClientExtensionSettings();
+  void InitializeExtensionSettings(GLDisplayEGL* display);
+  void UpdateConditionalExtensionSettings(GLDisplayEGL* display);
+
+  static std::string GetPlatformExtensions(GLDisplayEGL* display);
+
+ private:
+  static std::string GetClientExtensions();
+""")
   file.write('};\n')
   file.write('\n')
 
@@ -3254,6 +3312,8 @@
                    'ui/gl/gl_implementation.h',
                    'ui/gl/gl_version_info.h',
                    set_header_name ]
+  if set_name == 'egl':
+    include_list.append('ui/gl/gl_display.h')
 
   includes_string = "\n".join(["#include \"{0}\"".format(h)
                                for h in sorted(include_list)])
@@ -3311,6 +3371,10 @@
   for func in functions:
     if 'static_binding' in func:
       WriteFuncBinding(file, func['known_as'], func['static_binding'])
+    elif set_name == 'egl':
+      assert len(func['versions']) == 1
+      version = func['versions'][0]
+      WriteFuncBinding(file, func['known_as'], version['name'])
 
   def GetGLVersionCondition(gl_version):
     if GLVersionBindAlways(gl_version):
@@ -3373,7 +3437,7 @@
 """)
   elif set_name == 'egl':
     file.write("""\
-void DriverEGL::InitializeClientExtensionBindings() {
+void ExtensionsEGL::InitializeClientExtensionSettings() {
   std::string client_extensions(GetClientExtensions());
   [[maybe_unused]] gfx::ExtensionSet extensions(
       gfx::MakeExtensionSet(client_extensions));
@@ -3388,38 +3452,45 @@
 
 """ % (set_name.upper(),))
 
-  def OutputExtensionBindings(extension_var, extensions, extension_funcs):
+  def OutputExtensionSettings(extension_var, extensions, struct_qualifier):
     # Extra space at the end of the extension name is intentional,
     # it is used as a separator
     for extension in extensions:
-      file.write('  ext.b_%s = gfx::HasExtension(%s, "%s");\n' %
-                 (extension, extension_var, extension))
+      file.write('  %sb_%s = gfx::HasExtension(%s, "%s");\n' %
+                 (struct_qualifier, extension, extension_var, extension))
 
+  def OutputExtensionBindings(extension_funcs):
     for func in extension_funcs:
       if not 'static_binding' in func:
         file.write('\n')
         WriteConditionalFuncBinding(file, func)
 
-  OutputExtensionBindings(
+  OutputExtensionSettings(
     'extensions',
     sorted(used_client_extensions),
-    [ f for f in functions if IsClientExtensionFunc(f) ])
+    '' if set_name == 'egl' else 'ext.')
+  if set_name == 'gl' or set_name == 'glx':
+    OutputExtensionBindings(
+      [ f for f in functions if IsClientExtensionFunc(f) ])
 
   if set_name == 'egl':
     file.write("""\
 }
 
-void DriverEGL::InitializeExtensionBindings() {
-  std::string platform_extensions(GetPlatformExtensions());
+void ExtensionsEGL::InitializeExtensionSettings(GLDisplayEGL* display) {
+  std::string platform_extensions(GetPlatformExtensions(display));
   [[maybe_unused]] gfx::ExtensionSet extensions(
       gfx::MakeExtensionSet(platform_extensions));
 
 """)
 
-  OutputExtensionBindings(
+  OutputExtensionSettings(
     'extensions',
     sorted(used_extensions),
-    [ f for f in functions if not IsClientExtensionFunc(f) ])
+    '' if set_name == 'egl' else 'ext.')
+  if set_name == 'gl' or set_name == 'glx':
+    OutputExtensionBindings(
+      [ f for f in functions if not IsClientExtensionFunc(f) ])
   file.write('}\n')
 
   # Write function to clear all function pointers.
@@ -4077,6 +4148,10 @@
     used_extensions, used_client_extensions = FillExtensionsFromHeaders(
         functions, extension_headers, extensions)
 
+    if set_name == 'egl':
+      used_extensions.update(EGL_EXTENSIONS_EXTRA)
+      used_client_extensions.update(EGL_CLIENT_EXTENSIONS_EXTRA)
+
     header_file = open(
         os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'w')
     GenerateHeader(header_file, functions, set_name,
diff --git a/ui/gl/gl_bindings.cc b/ui/gl/gl_bindings.cc
index 13786d5..4889a32 100644
--- a/ui/gl/gl_bindings.cc
+++ b/ui/gl/gl_bindings.cc
@@ -16,21 +16,14 @@
 #endif
 
 #if defined(USE_EGL)
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_surface_egl.h"
 #endif
 
 namespace gl {
 
 #if defined(USE_EGL)
-std::string DriverEGL::GetPlatformExtensions() {
-  EGLDisplay display = GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay();
-  if (display == EGL_NO_DISPLAY)
-    return "";
-  const char* str = eglQueryString(display, EGL_EXTENSIONS);
-  return str ? std::string(str) : "";
-}
-
-void DriverEGL::UpdateConditionalExtensionBindings() {
+void ExtensionsEGL::UpdateConditionalExtensionSettings(GLDisplayEGL* display) {
   // For the moment, only two extensions can be conditionally disabled
   // through GPU driver bug workarounds mechanism:
   //   EGL_KHR_fence_sync
@@ -39,20 +32,27 @@
   // In theory it's OK to allow disabling other EGL extensions, as far as they
   // are not the ones used in GLSurfaceEGL::InitializeOneOff().
 
-  std::string extensions(GetPlatformExtensions());
+  std::string extensions(GetPlatformExtensions(display));
   extensions += " ";
 
-  ext.b_EGL_KHR_fence_sync =
+  b_EGL_KHR_fence_sync =
       extensions.find("EGL_KHR_fence_sync ") != std::string::npos;
-  ext.b_EGL_KHR_wait_sync =
+  b_EGL_KHR_wait_sync =
       extensions.find("EGL_KHR_wait_sync ") != std::string::npos;
-  if (!ext.b_EGL_KHR_wait_sync) {
-    fn.eglWaitSyncKHRFn = nullptr;
-  }
 }
 
 // static
-std::string DriverEGL::GetClientExtensions() {
+std::string ExtensionsEGL::GetPlatformExtensions(GLDisplayEGL* display) {
+  DCHECK(display);
+  EGLDisplay egl_display = display->GetHardwareDisplay();
+  if (egl_display == EGL_NO_DISPLAY)
+    return "";
+  const char* str = eglQueryString(egl_display, EGL_EXTENSIONS);
+  return str ? std::string(str) : "";
+}
+
+// static
+std::string ExtensionsEGL::GetClientExtensions() {
   const char* str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
   return str ? std::string(str) : "";
 }
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 93caac7..1d5b792 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -541,16 +541,10 @@
 #if defined(USE_EGL)
 struct GL_EXPORT DriverEGL {
   void InitializeStaticBindings();
-  void InitializeClientExtensionBindings();
-  void InitializeExtensionBindings();
   void ClearBindings();
-  void UpdateConditionalExtensionBindings();
 
   ProcsEGL fn;
   ExtensionsEGL ext;
-
-  static std::string GetPlatformExtensions();
-  static std::string GetClientExtensions();
 };
 #endif
 
diff --git a/ui/gl/gl_bindings_autogen_egl.cc b/ui/gl/gl_bindings_autogen_egl.cc
index 3c910e1..105d03f6 100644
--- a/ui/gl/gl_bindings_autogen_egl.cc
+++ b/ui/gl/gl_bindings_autogen_egl.cc
@@ -13,6 +13,7 @@
 #include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_egl_api_implementation.h"
 #include "ui/gl/gl_enums.h"
 #include "ui/gl/gl_implementation.h"
@@ -40,6 +41,8 @@
       reinterpret_cast<eglCopyBuffersProc>(GetGLProcAddress("eglCopyBuffers"));
   fn.eglCreateContextFn = reinterpret_cast<eglCreateContextProc>(
       GetGLProcAddress("eglCreateContext"));
+  fn.eglCreateImageKHRFn = reinterpret_cast<eglCreateImageKHRProc>(
+      GetGLProcAddress("eglCreateImageKHR"));
   fn.eglCreatePbufferFromClientBufferFn =
       reinterpret_cast<eglCreatePbufferFromClientBufferProc>(
           GetGLProcAddress("eglCreatePbufferFromClientBuffer"));
@@ -47,12 +50,24 @@
       GetGLProcAddress("eglCreatePbufferSurface"));
   fn.eglCreatePixmapSurfaceFn = reinterpret_cast<eglCreatePixmapSurfaceProc>(
       GetGLProcAddress("eglCreatePixmapSurface"));
+  fn.eglCreateStreamKHRFn = reinterpret_cast<eglCreateStreamKHRProc>(
+      GetGLProcAddress("eglCreateStreamKHR"));
+  fn.eglCreateStreamProducerD3DTextureANGLEFn =
+      reinterpret_cast<eglCreateStreamProducerD3DTextureANGLEProc>(
+          GetGLProcAddress("eglCreateStreamProducerD3DTextureANGLE"));
   fn.eglCreateSyncKHRFn = reinterpret_cast<eglCreateSyncKHRProc>(
       GetGLProcAddress("eglCreateSyncKHR"));
   fn.eglCreateWindowSurfaceFn = reinterpret_cast<eglCreateWindowSurfaceProc>(
       GetGLProcAddress("eglCreateWindowSurface"));
+  fn.eglDebugMessageControlKHRFn =
+      reinterpret_cast<eglDebugMessageControlKHRProc>(
+          GetGLProcAddress("eglDebugMessageControlKHR"));
   fn.eglDestroyContextFn = reinterpret_cast<eglDestroyContextProc>(
       GetGLProcAddress("eglDestroyContext"));
+  fn.eglDestroyImageKHRFn = reinterpret_cast<eglDestroyImageKHRProc>(
+      GetGLProcAddress("eglDestroyImageKHR"));
+  fn.eglDestroyStreamKHRFn = reinterpret_cast<eglDestroyStreamKHRProc>(
+      GetGLProcAddress("eglDestroyStreamKHR"));
   fn.eglDestroySurfaceFn = reinterpret_cast<eglDestroySurfaceProc>(
       GetGLProcAddress("eglDestroySurface"));
   fn.eglDestroySyncKHRFn = reinterpret_cast<eglDestroySyncKHRProc>(
@@ -60,6 +75,20 @@
   fn.eglDupNativeFenceFDANDROIDFn =
       reinterpret_cast<eglDupNativeFenceFDANDROIDProc>(
           GetGLProcAddress("eglDupNativeFenceFDANDROID"));
+  fn.eglExportDMABUFImageMESAFn =
+      reinterpret_cast<eglExportDMABUFImageMESAProc>(
+          GetGLProcAddress("eglExportDMABUFImageMESA"));
+  fn.eglExportDMABUFImageQueryMESAFn =
+      reinterpret_cast<eglExportDMABUFImageQueryMESAProc>(
+          GetGLProcAddress("eglExportDMABUFImageQueryMESA"));
+  fn.eglExportVkImageANGLEFn = reinterpret_cast<eglExportVkImageANGLEProc>(
+      GetGLProcAddress("eglExportVkImageANGLE"));
+  fn.eglGetCompositorTimingANDROIDFn =
+      reinterpret_cast<eglGetCompositorTimingANDROIDProc>(
+          GetGLProcAddress("eglGetCompositorTimingANDROID"));
+  fn.eglGetCompositorTimingSupportedANDROIDFn =
+      reinterpret_cast<eglGetCompositorTimingSupportedANDROIDProc>(
+          GetGLProcAddress("eglGetCompositorTimingSupportedANDROID"));
   fn.eglGetConfigAttribFn = reinterpret_cast<eglGetConfigAttribProc>(
       GetGLProcAddress("eglGetConfigAttrib"));
   fn.eglGetConfigsFn =
@@ -74,32 +103,116 @@
       reinterpret_cast<eglGetDisplayProc>(GetGLProcAddress("eglGetDisplay"));
   fn.eglGetErrorFn =
       reinterpret_cast<eglGetErrorProc>(GetGLProcAddress("eglGetError"));
+  fn.eglGetFrameTimestampsANDROIDFn =
+      reinterpret_cast<eglGetFrameTimestampsANDROIDProc>(
+          GetGLProcAddress("eglGetFrameTimestampsANDROID"));
+  fn.eglGetFrameTimestampSupportedANDROIDFn =
+      reinterpret_cast<eglGetFrameTimestampSupportedANDROIDProc>(
+          GetGLProcAddress("eglGetFrameTimestampSupportedANDROID"));
+  fn.eglGetMscRateANGLEFn = reinterpret_cast<eglGetMscRateANGLEProc>(
+      GetGLProcAddress("eglGetMscRateANGLE"));
+  fn.eglGetNativeClientBufferANDROIDFn =
+      reinterpret_cast<eglGetNativeClientBufferANDROIDProc>(
+          GetGLProcAddress("eglGetNativeClientBufferANDROID"));
+  fn.eglGetNextFrameIdANDROIDFn =
+      reinterpret_cast<eglGetNextFrameIdANDROIDProc>(
+          GetGLProcAddress("eglGetNextFrameIdANDROID"));
   fn.eglGetPlatformDisplayFn = reinterpret_cast<eglGetPlatformDisplayProc>(
       GetGLProcAddress("eglGetPlatformDisplay"));
   fn.eglGetProcAddressFn = reinterpret_cast<eglGetProcAddressProc>(
       GetGLProcAddress("eglGetProcAddress"));
   fn.eglGetSyncAttribKHRFn = reinterpret_cast<eglGetSyncAttribKHRProc>(
       GetGLProcAddress("eglGetSyncAttribKHR"));
+  fn.eglGetSyncValuesCHROMIUMFn =
+      reinterpret_cast<eglGetSyncValuesCHROMIUMProc>(
+          GetGLProcAddress("eglGetSyncValuesCHROMIUM"));
+  fn.eglHandleGPUSwitchANGLEFn = reinterpret_cast<eglHandleGPUSwitchANGLEProc>(
+      GetGLProcAddress("eglHandleGPUSwitchANGLE"));
+  fn.eglImageFlushExternalEXTFn =
+      reinterpret_cast<eglImageFlushExternalEXTProc>(
+          GetGLProcAddress("eglImageFlushExternalEXT"));
   fn.eglInitializeFn =
       reinterpret_cast<eglInitializeProc>(GetGLProcAddress("eglInitialize"));
+  fn.eglLabelObjectKHRFn = reinterpret_cast<eglLabelObjectKHRProc>(
+      GetGLProcAddress("eglLabelObjectKHR"));
   fn.eglMakeCurrentFn =
       reinterpret_cast<eglMakeCurrentProc>(GetGLProcAddress("eglMakeCurrent"));
+  fn.eglPostSubBufferNVFn = reinterpret_cast<eglPostSubBufferNVProc>(
+      GetGLProcAddress("eglPostSubBufferNV"));
   fn.eglQueryAPIFn =
       reinterpret_cast<eglQueryAPIProc>(GetGLProcAddress("eglQueryAPI"));
   fn.eglQueryContextFn = reinterpret_cast<eglQueryContextProc>(
       GetGLProcAddress("eglQueryContext"));
+  fn.eglQueryDebugKHRFn = reinterpret_cast<eglQueryDebugKHRProc>(
+      GetGLProcAddress("eglQueryDebugKHR"));
+  fn.eglQueryDeviceAttribEXTFn = reinterpret_cast<eglQueryDeviceAttribEXTProc>(
+      GetGLProcAddress("eglQueryDeviceAttribEXT"));
+  fn.eglQueryDevicesEXTFn = reinterpret_cast<eglQueryDevicesEXTProc>(
+      GetGLProcAddress("eglQueryDevicesEXT"));
+  fn.eglQueryDeviceStringEXTFn = reinterpret_cast<eglQueryDeviceStringEXTProc>(
+      GetGLProcAddress("eglQueryDeviceStringEXT"));
+  fn.eglQueryDisplayAttribANGLEFn =
+      reinterpret_cast<eglQueryDisplayAttribANGLEProc>(
+          GetGLProcAddress("eglQueryDisplayAttribANGLE"));
+  fn.eglQueryDisplayAttribEXTFn =
+      reinterpret_cast<eglQueryDisplayAttribEXTProc>(
+          GetGLProcAddress("eglQueryDisplayAttribEXT"));
+  fn.eglQueryDmaBufFormatsEXTFn =
+      reinterpret_cast<eglQueryDmaBufFormatsEXTProc>(
+          GetGLProcAddress("eglQueryDmaBufFormatsEXT"));
+  fn.eglQueryDmaBufModifiersEXTFn =
+      reinterpret_cast<eglQueryDmaBufModifiersEXTProc>(
+          GetGLProcAddress("eglQueryDmaBufModifiersEXT"));
+  fn.eglQueryStreamKHRFn = reinterpret_cast<eglQueryStreamKHRProc>(
+      GetGLProcAddress("eglQueryStreamKHR"));
+  fn.eglQueryStreamu64KHRFn = reinterpret_cast<eglQueryStreamu64KHRProc>(
+      GetGLProcAddress("eglQueryStreamu64KHR"));
   fn.eglQueryStringFn =
       reinterpret_cast<eglQueryStringProc>(GetGLProcAddress("eglQueryString"));
+  fn.eglQueryStringiANGLEFn = reinterpret_cast<eglQueryStringiANGLEProc>(
+      GetGLProcAddress("eglQueryStringiANGLE"));
   fn.eglQuerySurfaceFn = reinterpret_cast<eglQuerySurfaceProc>(
       GetGLProcAddress("eglQuerySurface"));
+  fn.eglQuerySurfacePointerANGLEFn =
+      reinterpret_cast<eglQuerySurfacePointerANGLEProc>(
+          GetGLProcAddress("eglQuerySurfacePointerANGLE"));
+  fn.eglReacquireHighPowerGPUANGLEFn =
+      reinterpret_cast<eglReacquireHighPowerGPUANGLEProc>(
+          GetGLProcAddress("eglReacquireHighPowerGPUANGLE"));
+  fn.eglReleaseHighPowerGPUANGLEFn =
+      reinterpret_cast<eglReleaseHighPowerGPUANGLEProc>(
+          GetGLProcAddress("eglReleaseHighPowerGPUANGLE"));
   fn.eglReleaseTexImageFn = reinterpret_cast<eglReleaseTexImageProc>(
       GetGLProcAddress("eglReleaseTexImage"));
   fn.eglReleaseThreadFn = reinterpret_cast<eglReleaseThreadProc>(
       GetGLProcAddress("eglReleaseThread"));
+  fn.eglSetBlobCacheFuncsANDROIDFn =
+      reinterpret_cast<eglSetBlobCacheFuncsANDROIDProc>(
+          GetGLProcAddress("eglSetBlobCacheFuncsANDROID"));
+  fn.eglStreamAttribKHRFn = reinterpret_cast<eglStreamAttribKHRProc>(
+      GetGLProcAddress("eglStreamAttribKHR"));
+  fn.eglStreamConsumerAcquireKHRFn =
+      reinterpret_cast<eglStreamConsumerAcquireKHRProc>(
+          GetGLProcAddress("eglStreamConsumerAcquireKHR"));
+  fn.eglStreamConsumerGLTextureExternalAttribsNVFn =
+      reinterpret_cast<eglStreamConsumerGLTextureExternalAttribsNVProc>(
+          GetGLProcAddress("eglStreamConsumerGLTextureExternalAttribsNV"));
+  fn.eglStreamConsumerGLTextureExternalKHRFn =
+      reinterpret_cast<eglStreamConsumerGLTextureExternalKHRProc>(
+          GetGLProcAddress("eglStreamConsumerGLTextureExternalKHR"));
+  fn.eglStreamConsumerReleaseKHRFn =
+      reinterpret_cast<eglStreamConsumerReleaseKHRProc>(
+          GetGLProcAddress("eglStreamConsumerReleaseKHR"));
+  fn.eglStreamPostD3DTextureANGLEFn =
+      reinterpret_cast<eglStreamPostD3DTextureANGLEProc>(
+          GetGLProcAddress("eglStreamPostD3DTextureANGLE"));
   fn.eglSurfaceAttribFn = reinterpret_cast<eglSurfaceAttribProc>(
       GetGLProcAddress("eglSurfaceAttrib"));
   fn.eglSwapBuffersFn =
       reinterpret_cast<eglSwapBuffersProc>(GetGLProcAddress("eglSwapBuffers"));
+  fn.eglSwapBuffersWithDamageKHRFn =
+      reinterpret_cast<eglSwapBuffersWithDamageKHRProc>(
+          GetGLProcAddress("eglSwapBuffersWithDamageKHR"));
   fn.eglSwapIntervalFn = reinterpret_cast<eglSwapIntervalProc>(
       GetGLProcAddress("eglSwapInterval"));
   fn.eglTerminateFn =
@@ -110,330 +223,143 @@
       reinterpret_cast<eglWaitGLProc>(GetGLProcAddress("eglWaitGL"));
   fn.eglWaitNativeFn =
       reinterpret_cast<eglWaitNativeProc>(GetGLProcAddress("eglWaitNative"));
+  fn.eglWaitSyncKHRFn =
+      reinterpret_cast<eglWaitSyncKHRProc>(GetGLProcAddress("eglWaitSyncKHR"));
 }
 
-void DriverEGL::InitializeClientExtensionBindings() {
+void ExtensionsEGL::InitializeClientExtensionSettings() {
   std::string client_extensions(GetClientExtensions());
   [[maybe_unused]] gfx::ExtensionSet extensions(
       gfx::MakeExtensionSet(client_extensions));
 
-  ext.b_EGL_ANGLE_feature_control =
+  b_EGL_ANGLE_display_power_preference =
+      gfx::HasExtension(extensions, "EGL_ANGLE_display_power_preference");
+  b_EGL_ANGLE_feature_control =
       gfx::HasExtension(extensions, "EGL_ANGLE_feature_control");
-  ext.b_EGL_EXT_device_base =
-      gfx::HasExtension(extensions, "EGL_EXT_device_base");
-  ext.b_EGL_EXT_device_enumeration =
+  b_EGL_ANGLE_platform_angle =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle");
+  b_EGL_ANGLE_platform_angle_d3d =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_d3d");
+  b_EGL_ANGLE_platform_angle_device_id =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_device_id");
+  b_EGL_ANGLE_platform_angle_device_type_egl_angle = gfx::HasExtension(
+      extensions, "EGL_ANGLE_platform_angle_device_type_egl_angle");
+  b_EGL_ANGLE_platform_angle_device_type_swiftshader = gfx::HasExtension(
+      extensions, "EGL_ANGLE_platform_angle_device_type_swiftshader");
+  b_EGL_ANGLE_platform_angle_metal =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_metal");
+  b_EGL_ANGLE_platform_angle_null =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_null");
+  b_EGL_ANGLE_platform_angle_opengl =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_opengl");
+  b_EGL_ANGLE_platform_angle_vulkan =
+      gfx::HasExtension(extensions, "EGL_ANGLE_platform_angle_vulkan");
+  b_EGL_EXT_device_base = gfx::HasExtension(extensions, "EGL_EXT_device_base");
+  b_EGL_EXT_device_enumeration =
       gfx::HasExtension(extensions, "EGL_EXT_device_enumeration");
-  ext.b_EGL_EXT_device_query =
+  b_EGL_EXT_device_query =
       gfx::HasExtension(extensions, "EGL_EXT_device_query");
-  ext.b_EGL_KHR_debug = gfx::HasExtension(extensions, "EGL_KHR_debug");
-
-  if (ext.b_EGL_KHR_debug) {
-    fn.eglDebugMessageControlKHRFn =
-        reinterpret_cast<eglDebugMessageControlKHRProc>(
-            GetGLProcAddress("eglDebugMessageControlKHR"));
-  }
-
-  if (ext.b_EGL_KHR_debug) {
-    fn.eglLabelObjectKHRFn = reinterpret_cast<eglLabelObjectKHRProc>(
-        GetGLProcAddress("eglLabelObjectKHR"));
-  }
-
-  if (ext.b_EGL_KHR_debug) {
-    fn.eglQueryDebugKHRFn = reinterpret_cast<eglQueryDebugKHRProc>(
-        GetGLProcAddress("eglQueryDebugKHR"));
-  }
-
-  if (ext.b_EGL_EXT_device_base || ext.b_EGL_EXT_device_query) {
-    fn.eglQueryDeviceAttribEXTFn =
-        reinterpret_cast<eglQueryDeviceAttribEXTProc>(
-            GetGLProcAddress("eglQueryDeviceAttribEXT"));
-  }
-
-  if (ext.b_EGL_EXT_device_base || ext.b_EGL_EXT_device_enumeration) {
-    fn.eglQueryDevicesEXTFn = reinterpret_cast<eglQueryDevicesEXTProc>(
-        GetGLProcAddress("eglQueryDevicesEXT"));
-  }
-
-  if (ext.b_EGL_EXT_device_base || ext.b_EGL_EXT_device_query) {
-    fn.eglQueryDeviceStringEXTFn =
-        reinterpret_cast<eglQueryDeviceStringEXTProc>(
-            GetGLProcAddress("eglQueryDeviceStringEXT"));
-  }
-
-  if (ext.b_EGL_ANGLE_feature_control) {
-    fn.eglQueryDisplayAttribANGLEFn =
-        reinterpret_cast<eglQueryDisplayAttribANGLEProc>(
-            GetGLProcAddress("eglQueryDisplayAttribANGLE"));
-  }
-
-  if (ext.b_EGL_EXT_device_base || ext.b_EGL_EXT_device_query) {
-    fn.eglQueryDisplayAttribEXTFn =
-        reinterpret_cast<eglQueryDisplayAttribEXTProc>(
-            GetGLProcAddress("eglQueryDisplayAttribEXT"));
-  }
-
-  if (ext.b_EGL_ANGLE_feature_control) {
-    fn.eglQueryStringiANGLEFn = reinterpret_cast<eglQueryStringiANGLEProc>(
-        GetGLProcAddress("eglQueryStringiANGLE"));
-  }
+  b_EGL_EXT_platform_device =
+      gfx::HasExtension(extensions, "EGL_EXT_platform_device");
+  b_EGL_KHR_debug = gfx::HasExtension(extensions, "EGL_KHR_debug");
+  b_EGL_MESA_platform_surfaceless =
+      gfx::HasExtension(extensions, "EGL_MESA_platform_surfaceless");
 }
 
-void DriverEGL::InitializeExtensionBindings() {
-  std::string platform_extensions(GetPlatformExtensions());
+void ExtensionsEGL::InitializeExtensionSettings(GLDisplayEGL* display) {
+  std::string platform_extensions(GetPlatformExtensions(display));
   [[maybe_unused]] gfx::ExtensionSet extensions(
       gfx::MakeExtensionSet(platform_extensions));
 
-  ext.b_EGL_ANDROID_blob_cache =
+  b_EGL_ANDROID_blob_cache =
       gfx::HasExtension(extensions, "EGL_ANDROID_blob_cache");
-  ext.b_EGL_ANDROID_get_frame_timestamps =
+  b_EGL_ANDROID_create_native_client_buffer =
+      gfx::HasExtension(extensions, "EGL_ANDROID_create_native_client_buffer");
+  b_EGL_ANDROID_front_buffer_auto_refresh =
+      gfx::HasExtension(extensions, "EGL_ANDROID_front_buffer_auto_refresh");
+  b_EGL_ANDROID_get_frame_timestamps =
       gfx::HasExtension(extensions, "EGL_ANDROID_get_frame_timestamps");
-  ext.b_EGL_ANDROID_get_native_client_buffer =
+  b_EGL_ANDROID_get_native_client_buffer =
       gfx::HasExtension(extensions, "EGL_ANDROID_get_native_client_buffer");
-  ext.b_EGL_ANDROID_native_fence_sync =
+  b_EGL_ANDROID_native_fence_sync =
       gfx::HasExtension(extensions, "EGL_ANDROID_native_fence_sync");
-  ext.b_EGL_ANGLE_d3d_share_handle_client_buffer =
+  b_EGL_ANGLE_context_virtualization =
+      gfx::HasExtension(extensions, "EGL_ANGLE_context_virtualization");
+  b_EGL_ANGLE_create_context_client_arrays =
+      gfx::HasExtension(extensions, "EGL_ANGLE_create_context_client_arrays");
+  b_EGL_ANGLE_create_context_webgl_compatibility = gfx::HasExtension(
+      extensions, "EGL_ANGLE_create_context_webgl_compatibility");
+  b_EGL_ANGLE_d3d_share_handle_client_buffer =
       gfx::HasExtension(extensions, "EGL_ANGLE_d3d_share_handle_client_buffer");
-  ext.b_EGL_ANGLE_power_preference =
+  b_EGL_ANGLE_display_semaphore_share_group =
+      gfx::HasExtension(extensions, "EGL_ANGLE_display_semaphore_share_group");
+  b_EGL_ANGLE_display_texture_share_group =
+      gfx::HasExtension(extensions, "EGL_ANGLE_display_texture_share_group");
+  b_EGL_ANGLE_external_context_and_surface =
+      gfx::HasExtension(extensions, "EGL_ANGLE_external_context_and_surface");
+  b_EGL_ANGLE_power_preference =
       gfx::HasExtension(extensions, "EGL_ANGLE_power_preference");
-  ext.b_EGL_ANGLE_query_surface_pointer =
+  b_EGL_ANGLE_query_surface_pointer =
       gfx::HasExtension(extensions, "EGL_ANGLE_query_surface_pointer");
-  ext.b_EGL_ANGLE_stream_producer_d3d_texture =
+  b_EGL_ANGLE_stream_producer_d3d_texture =
       gfx::HasExtension(extensions, "EGL_ANGLE_stream_producer_d3d_texture");
-  ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle = gfx::HasExtension(
+  b_EGL_ANGLE_surface_d3d_texture_2d_share_handle = gfx::HasExtension(
       extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle");
-  ext.b_EGL_ANGLE_sync_control_rate =
+  b_EGL_ANGLE_surface_orientation =
+      gfx::HasExtension(extensions, "EGL_ANGLE_surface_orientation");
+  b_EGL_ANGLE_sync_control_rate =
       gfx::HasExtension(extensions, "EGL_ANGLE_sync_control_rate");
-  ext.b_EGL_ANGLE_vulkan_image =
+  b_EGL_ANGLE_vulkan_image =
       gfx::HasExtension(extensions, "EGL_ANGLE_vulkan_image");
-  ext.b_EGL_CHROMIUM_sync_control =
+  b_EGL_ANGLE_window_fixed_size =
+      gfx::HasExtension(extensions, "EGL_ANGLE_window_fixed_size");
+  b_EGL_CHROMIUM_create_context_bind_generates_resource = gfx::HasExtension(
+      extensions, "EGL_CHROMIUM_create_context_bind_generates_resource");
+  b_EGL_CHROMIUM_sync_control =
       gfx::HasExtension(extensions, "EGL_CHROMIUM_sync_control");
-  ext.b_EGL_EXT_image_dma_buf_import_modifiers =
+  b_EGL_EXT_create_context_robustness =
+      gfx::HasExtension(extensions, "EGL_EXT_create_context_robustness");
+  b_EGL_EXT_gl_colorspace_display_p3 =
+      gfx::HasExtension(extensions, "EGL_EXT_gl_colorspace_display_p3");
+  b_EGL_EXT_gl_colorspace_display_p3_passthrough = gfx::HasExtension(
+      extensions, "EGL_EXT_gl_colorspace_display_p3_passthrough");
+  b_EGL_EXT_image_dma_buf_import_modifiers =
       gfx::HasExtension(extensions, "EGL_EXT_image_dma_buf_import_modifiers");
-  ext.b_EGL_EXT_image_flush_external =
+  b_EGL_EXT_image_flush_external =
       gfx::HasExtension(extensions, "EGL_EXT_image_flush_external");
-  ext.b_EGL_KHR_fence_sync =
-      gfx::HasExtension(extensions, "EGL_KHR_fence_sync");
-  ext.b_EGL_KHR_gl_texture_2D_image =
+  b_EGL_EXT_pixel_format_float =
+      gfx::HasExtension(extensions, "EGL_EXT_pixel_format_float");
+  b_EGL_IMG_context_priority =
+      gfx::HasExtension(extensions, "EGL_IMG_context_priority");
+  b_EGL_KHR_fence_sync = gfx::HasExtension(extensions, "EGL_KHR_fence_sync");
+  b_EGL_KHR_gl_colorspace =
+      gfx::HasExtension(extensions, "EGL_KHR_gl_colorspace");
+  b_EGL_KHR_gl_texture_2D_image =
       gfx::HasExtension(extensions, "EGL_KHR_gl_texture_2D_image");
-  ext.b_EGL_KHR_image = gfx::HasExtension(extensions, "EGL_KHR_image");
-  ext.b_EGL_KHR_image_base =
-      gfx::HasExtension(extensions, "EGL_KHR_image_base");
-  ext.b_EGL_KHR_stream = gfx::HasExtension(extensions, "EGL_KHR_stream");
-  ext.b_EGL_KHR_stream_consumer_gltexture =
+  b_EGL_KHR_image = gfx::HasExtension(extensions, "EGL_KHR_image");
+  b_EGL_KHR_image_base = gfx::HasExtension(extensions, "EGL_KHR_image_base");
+  b_EGL_KHR_no_config_context =
+      gfx::HasExtension(extensions, "EGL_KHR_no_config_context");
+  b_EGL_KHR_stream = gfx::HasExtension(extensions, "EGL_KHR_stream");
+  b_EGL_KHR_stream_consumer_gltexture =
       gfx::HasExtension(extensions, "EGL_KHR_stream_consumer_gltexture");
-  ext.b_EGL_KHR_swap_buffers_with_damage =
+  b_EGL_KHR_surfaceless_context =
+      gfx::HasExtension(extensions, "EGL_KHR_surfaceless_context");
+  b_EGL_KHR_swap_buffers_with_damage =
       gfx::HasExtension(extensions, "EGL_KHR_swap_buffers_with_damage");
-  ext.b_EGL_KHR_wait_sync = gfx::HasExtension(extensions, "EGL_KHR_wait_sync");
-  ext.b_EGL_MESA_image_dma_buf_export =
+  b_EGL_KHR_wait_sync = gfx::HasExtension(extensions, "EGL_KHR_wait_sync");
+  b_EGL_MESA_image_dma_buf_export =
       gfx::HasExtension(extensions, "EGL_MESA_image_dma_buf_export");
-  ext.b_EGL_NV_post_sub_buffer =
+  b_EGL_NV_post_sub_buffer =
       gfx::HasExtension(extensions, "EGL_NV_post_sub_buffer");
-  ext.b_EGL_NV_stream_consumer_gltexture_yuv =
+  b_EGL_NV_robustness_video_memory_purge =
+      gfx::HasExtension(extensions, "EGL_NV_robustness_video_memory_purge");
+  b_EGL_NV_stream_consumer_gltexture_yuv =
       gfx::HasExtension(extensions, "EGL_NV_stream_consumer_gltexture_yuv");
-  ext.b_GL_CHROMIUM_egl_android_native_fence_sync_hack = gfx::HasExtension(
+  b_GL_CHROMIUM_egl_android_native_fence_sync_hack = gfx::HasExtension(
       extensions, "GL_CHROMIUM_egl_android_native_fence_sync_hack");
-  ext.b_GL_CHROMIUM_egl_khr_fence_sync_hack =
+  b_GL_CHROMIUM_egl_khr_fence_sync_hack =
       gfx::HasExtension(extensions, "GL_CHROMIUM_egl_khr_fence_sync_hack");
-
-  if (ext.b_EGL_KHR_gl_texture_2D_image || ext.b_EGL_KHR_image ||
-      ext.b_EGL_KHR_image_base) {
-    fn.eglCreateImageKHRFn = reinterpret_cast<eglCreateImageKHRProc>(
-        GetGLProcAddress("eglCreateImageKHR"));
-  }
-
-  if (ext.b_EGL_KHR_stream) {
-    fn.eglCreateStreamKHRFn = reinterpret_cast<eglCreateStreamKHRProc>(
-        GetGLProcAddress("eglCreateStreamKHR"));
-  }
-
-  if (ext.b_EGL_ANGLE_stream_producer_d3d_texture) {
-    fn.eglCreateStreamProducerD3DTextureANGLEFn =
-        reinterpret_cast<eglCreateStreamProducerD3DTextureANGLEProc>(
-            GetGLProcAddress("eglCreateStreamProducerD3DTextureANGLE"));
-  }
-
-  if (ext.b_EGL_KHR_image || ext.b_EGL_KHR_image_base) {
-    fn.eglDestroyImageKHRFn = reinterpret_cast<eglDestroyImageKHRProc>(
-        GetGLProcAddress("eglDestroyImageKHR"));
-  }
-
-  if (ext.b_EGL_KHR_stream) {
-    fn.eglDestroyStreamKHRFn = reinterpret_cast<eglDestroyStreamKHRProc>(
-        GetGLProcAddress("eglDestroyStreamKHR"));
-  }
-
-  if (ext.b_EGL_MESA_image_dma_buf_export) {
-    fn.eglExportDMABUFImageMESAFn =
-        reinterpret_cast<eglExportDMABUFImageMESAProc>(
-            GetGLProcAddress("eglExportDMABUFImageMESA"));
-  }
-
-  if (ext.b_EGL_MESA_image_dma_buf_export) {
-    fn.eglExportDMABUFImageQueryMESAFn =
-        reinterpret_cast<eglExportDMABUFImageQueryMESAProc>(
-            GetGLProcAddress("eglExportDMABUFImageQueryMESA"));
-  }
-
-  if (ext.b_EGL_ANGLE_vulkan_image) {
-    fn.eglExportVkImageANGLEFn = reinterpret_cast<eglExportVkImageANGLEProc>(
-        GetGLProcAddress("eglExportVkImageANGLE"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_frame_timestamps) {
-    fn.eglGetCompositorTimingANDROIDFn =
-        reinterpret_cast<eglGetCompositorTimingANDROIDProc>(
-            GetGLProcAddress("eglGetCompositorTimingANDROID"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_frame_timestamps) {
-    fn.eglGetCompositorTimingSupportedANDROIDFn =
-        reinterpret_cast<eglGetCompositorTimingSupportedANDROIDProc>(
-            GetGLProcAddress("eglGetCompositorTimingSupportedANDROID"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_frame_timestamps) {
-    fn.eglGetFrameTimestampsANDROIDFn =
-        reinterpret_cast<eglGetFrameTimestampsANDROIDProc>(
-            GetGLProcAddress("eglGetFrameTimestampsANDROID"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_frame_timestamps) {
-    fn.eglGetFrameTimestampSupportedANDROIDFn =
-        reinterpret_cast<eglGetFrameTimestampSupportedANDROIDProc>(
-            GetGLProcAddress("eglGetFrameTimestampSupportedANDROID"));
-  }
-
-  if (ext.b_EGL_ANGLE_sync_control_rate) {
-    fn.eglGetMscRateANGLEFn = reinterpret_cast<eglGetMscRateANGLEProc>(
-        GetGLProcAddress("eglGetMscRateANGLE"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_native_client_buffer) {
-    fn.eglGetNativeClientBufferANDROIDFn =
-        reinterpret_cast<eglGetNativeClientBufferANDROIDProc>(
-            GetGLProcAddress("eglGetNativeClientBufferANDROID"));
-  }
-
-  if (ext.b_EGL_ANDROID_get_frame_timestamps) {
-    fn.eglGetNextFrameIdANDROIDFn =
-        reinterpret_cast<eglGetNextFrameIdANDROIDProc>(
-            GetGLProcAddress("eglGetNextFrameIdANDROID"));
-  }
-
-  if (ext.b_EGL_CHROMIUM_sync_control) {
-    fn.eglGetSyncValuesCHROMIUMFn =
-        reinterpret_cast<eglGetSyncValuesCHROMIUMProc>(
-            GetGLProcAddress("eglGetSyncValuesCHROMIUM"));
-  }
-
-  if (ext.b_EGL_ANGLE_power_preference) {
-    fn.eglHandleGPUSwitchANGLEFn =
-        reinterpret_cast<eglHandleGPUSwitchANGLEProc>(
-            GetGLProcAddress("eglHandleGPUSwitchANGLE"));
-  }
-
-  if (ext.b_EGL_EXT_image_flush_external) {
-    fn.eglImageFlushExternalEXTFn =
-        reinterpret_cast<eglImageFlushExternalEXTProc>(
-            GetGLProcAddress("eglImageFlushExternalEXT"));
-  }
-
-  if (ext.b_EGL_NV_post_sub_buffer) {
-    fn.eglPostSubBufferNVFn = reinterpret_cast<eglPostSubBufferNVProc>(
-        GetGLProcAddress("eglPostSubBufferNV"));
-  }
-
-  if (ext.b_EGL_EXT_image_dma_buf_import_modifiers) {
-    fn.eglQueryDmaBufFormatsEXTFn =
-        reinterpret_cast<eglQueryDmaBufFormatsEXTProc>(
-            GetGLProcAddress("eglQueryDmaBufFormatsEXT"));
-  }
-
-  if (ext.b_EGL_EXT_image_dma_buf_import_modifiers) {
-    fn.eglQueryDmaBufModifiersEXTFn =
-        reinterpret_cast<eglQueryDmaBufModifiersEXTProc>(
-            GetGLProcAddress("eglQueryDmaBufModifiersEXT"));
-  }
-
-  if (ext.b_EGL_KHR_stream) {
-    fn.eglQueryStreamKHRFn = reinterpret_cast<eglQueryStreamKHRProc>(
-        GetGLProcAddress("eglQueryStreamKHR"));
-  }
-
-  if (ext.b_EGL_KHR_stream) {
-    fn.eglQueryStreamu64KHRFn = reinterpret_cast<eglQueryStreamu64KHRProc>(
-        GetGLProcAddress("eglQueryStreamu64KHR"));
-  }
-
-  if (ext.b_EGL_ANGLE_query_surface_pointer) {
-    fn.eglQuerySurfacePointerANGLEFn =
-        reinterpret_cast<eglQuerySurfacePointerANGLEProc>(
-            GetGLProcAddress("eglQuerySurfacePointerANGLE"));
-  }
-
-  if (ext.b_EGL_ANGLE_power_preference) {
-    fn.eglReacquireHighPowerGPUANGLEFn =
-        reinterpret_cast<eglReacquireHighPowerGPUANGLEProc>(
-            GetGLProcAddress("eglReacquireHighPowerGPUANGLE"));
-  }
-
-  if (ext.b_EGL_ANGLE_power_preference) {
-    fn.eglReleaseHighPowerGPUANGLEFn =
-        reinterpret_cast<eglReleaseHighPowerGPUANGLEProc>(
-            GetGLProcAddress("eglReleaseHighPowerGPUANGLE"));
-  }
-
-  if (ext.b_EGL_ANDROID_blob_cache) {
-    fn.eglSetBlobCacheFuncsANDROIDFn =
-        reinterpret_cast<eglSetBlobCacheFuncsANDROIDProc>(
-            GetGLProcAddress("eglSetBlobCacheFuncsANDROID"));
-  }
-
-  if (ext.b_EGL_KHR_stream) {
-    fn.eglStreamAttribKHRFn = reinterpret_cast<eglStreamAttribKHRProc>(
-        GetGLProcAddress("eglStreamAttribKHR"));
-  }
-
-  if (ext.b_EGL_KHR_stream_consumer_gltexture) {
-    fn.eglStreamConsumerAcquireKHRFn =
-        reinterpret_cast<eglStreamConsumerAcquireKHRProc>(
-            GetGLProcAddress("eglStreamConsumerAcquireKHR"));
-  }
-
-  if (ext.b_EGL_NV_stream_consumer_gltexture_yuv) {
-    fn.eglStreamConsumerGLTextureExternalAttribsNVFn =
-        reinterpret_cast<eglStreamConsumerGLTextureExternalAttribsNVProc>(
-            GetGLProcAddress("eglStreamConsumerGLTextureExternalAttribsNV"));
-  }
-
-  if (ext.b_EGL_KHR_stream_consumer_gltexture) {
-    fn.eglStreamConsumerGLTextureExternalKHRFn =
-        reinterpret_cast<eglStreamConsumerGLTextureExternalKHRProc>(
-            GetGLProcAddress("eglStreamConsumerGLTextureExternalKHR"));
-  }
-
-  if (ext.b_EGL_KHR_stream_consumer_gltexture) {
-    fn.eglStreamConsumerReleaseKHRFn =
-        reinterpret_cast<eglStreamConsumerReleaseKHRProc>(
-            GetGLProcAddress("eglStreamConsumerReleaseKHR"));
-  }
-
-  if (ext.b_EGL_ANGLE_stream_producer_d3d_texture) {
-    fn.eglStreamPostD3DTextureANGLEFn =
-        reinterpret_cast<eglStreamPostD3DTextureANGLEProc>(
-            GetGLProcAddress("eglStreamPostD3DTextureANGLE"));
-  }
-
-  if (ext.b_EGL_KHR_swap_buffers_with_damage) {
-    fn.eglSwapBuffersWithDamageKHRFn =
-        reinterpret_cast<eglSwapBuffersWithDamageKHRProc>(
-            GetGLProcAddress("eglSwapBuffersWithDamageKHR"));
-  }
-
-  if (ext.b_EGL_KHR_wait_sync) {
-    fn.eglWaitSyncKHRFn = reinterpret_cast<eglWaitSyncKHRProc>(
-        GetGLProcAddress("eglWaitSyncKHR"));
-  }
 }
 
 void DriverEGL::ClearBindings() {
diff --git a/ui/gl/gl_bindings_autogen_egl.h b/ui/gl/gl_bindings_autogen_egl.h
index 299f7a94..1245282 100644
--- a/ui/gl/gl_bindings_autogen_egl.h
+++ b/ui/gl/gl_bindings_autogen_egl.h
@@ -16,6 +16,7 @@
 namespace gl {
 
 class GLContext;
+class GLDisplayEGL;
 
 typedef EGLBoolean(GL_BINDING_CALL* eglBindAPIProc)(EGLenum api);
 typedef EGLBoolean(GL_BINDING_CALL* eglBindTexImageProc)(EGLDisplay dpy,
@@ -313,39 +314,80 @@
                                                     EGLSyncKHR sync,
                                                     EGLint flags);
 
-struct ExtensionsEGL {
+struct GL_EXPORT ExtensionsEGL {
+  bool b_EGL_ANGLE_display_power_preference;
   bool b_EGL_ANGLE_feature_control;
+  bool b_EGL_ANGLE_platform_angle;
+  bool b_EGL_ANGLE_platform_angle_d3d;
+  bool b_EGL_ANGLE_platform_angle_device_id;
+  bool b_EGL_ANGLE_platform_angle_device_type_egl_angle;
+  bool b_EGL_ANGLE_platform_angle_device_type_swiftshader;
+  bool b_EGL_ANGLE_platform_angle_metal;
+  bool b_EGL_ANGLE_platform_angle_null;
+  bool b_EGL_ANGLE_platform_angle_opengl;
+  bool b_EGL_ANGLE_platform_angle_vulkan;
   bool b_EGL_EXT_device_base;
   bool b_EGL_EXT_device_enumeration;
   bool b_EGL_EXT_device_query;
+  bool b_EGL_EXT_platform_device;
   bool b_EGL_KHR_debug;
+  bool b_EGL_MESA_platform_surfaceless;
   bool b_EGL_ANDROID_blob_cache;
+  bool b_EGL_ANDROID_create_native_client_buffer;
+  bool b_EGL_ANDROID_front_buffer_auto_refresh;
   bool b_EGL_ANDROID_get_frame_timestamps;
   bool b_EGL_ANDROID_get_native_client_buffer;
   bool b_EGL_ANDROID_native_fence_sync;
+  bool b_EGL_ANGLE_context_virtualization;
+  bool b_EGL_ANGLE_create_context_client_arrays;
+  bool b_EGL_ANGLE_create_context_webgl_compatibility;
   bool b_EGL_ANGLE_d3d_share_handle_client_buffer;
+  bool b_EGL_ANGLE_display_semaphore_share_group;
+  bool b_EGL_ANGLE_display_texture_share_group;
+  bool b_EGL_ANGLE_external_context_and_surface;
   bool b_EGL_ANGLE_power_preference;
   bool b_EGL_ANGLE_query_surface_pointer;
   bool b_EGL_ANGLE_stream_producer_d3d_texture;
   bool b_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
+  bool b_EGL_ANGLE_surface_orientation;
   bool b_EGL_ANGLE_sync_control_rate;
   bool b_EGL_ANGLE_vulkan_image;
+  bool b_EGL_ANGLE_window_fixed_size;
+  bool b_EGL_CHROMIUM_create_context_bind_generates_resource;
   bool b_EGL_CHROMIUM_sync_control;
+  bool b_EGL_EXT_create_context_robustness;
+  bool b_EGL_EXT_gl_colorspace_display_p3;
+  bool b_EGL_EXT_gl_colorspace_display_p3_passthrough;
   bool b_EGL_EXT_image_dma_buf_import_modifiers;
   bool b_EGL_EXT_image_flush_external;
+  bool b_EGL_EXT_pixel_format_float;
+  bool b_EGL_IMG_context_priority;
   bool b_EGL_KHR_fence_sync;
+  bool b_EGL_KHR_gl_colorspace;
   bool b_EGL_KHR_gl_texture_2D_image;
   bool b_EGL_KHR_image;
   bool b_EGL_KHR_image_base;
+  bool b_EGL_KHR_no_config_context;
   bool b_EGL_KHR_stream;
   bool b_EGL_KHR_stream_consumer_gltexture;
+  bool b_EGL_KHR_surfaceless_context;
   bool b_EGL_KHR_swap_buffers_with_damage;
   bool b_EGL_KHR_wait_sync;
   bool b_EGL_MESA_image_dma_buf_export;
   bool b_EGL_NV_post_sub_buffer;
+  bool b_EGL_NV_robustness_video_memory_purge;
   bool b_EGL_NV_stream_consumer_gltexture_yuv;
   bool b_GL_CHROMIUM_egl_android_native_fence_sync_hack;
   bool b_GL_CHROMIUM_egl_khr_fence_sync_hack;
+
+  void InitializeClientExtensionSettings();
+  void InitializeExtensionSettings(GLDisplayEGL* display);
+  void UpdateConditionalExtensionSettings(GLDisplayEGL* display);
+
+  static std::string GetPlatformExtensions(GLDisplayEGL* display);
+
+ private:
+  static std::string GetClientExtensions();
 };
 
 struct ProcsEGL {
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc
index 5ed98c826..66404d3 100644
--- a/ui/gl/gl_context_egl.cc
+++ b/ui/gl/gl_context_egl.cc
@@ -15,6 +15,7 @@
 #include "third_party/khronos/EGL/eglext.h"
 #include "ui/gl/egl_util.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_fence.h"
 #include "ui/gl/gl_gl_api_implementation.h"
 #include "ui/gl/gl_surface_egl.h"
@@ -121,18 +122,19 @@
   DCHECK(compatible_surface);
   DCHECK(!context_);
 
-  display_ = compatible_surface->GetGLDisplay()->GetDisplay();
+  gl_display_ = static_cast<GLDisplayEGL*>(compatible_surface->GetGLDisplay());
+  DCHECK(gl_display_);
 
   EGLint context_client_major_version = attribs.client_major_es_version;
   EGLint context_client_minor_version = attribs.client_minor_es_version;
 
   // Always prefer to use EGL_KHR_no_config_context so that all surfaces and
   // contexts are compatible
-  if (!GLSurfaceEGL::GetGLDisplayEGL()->IsEGLNoConfigContextSupported()) {
+  if (!gl_display_->IsEGLNoConfigContextSupported()) {
     config_ = compatible_surface->GetConfig();
     EGLint config_renderable_type = 0;
-    if (!eglGetConfigAttrib(display_, config_, EGL_RENDERABLE_TYPE,
-                            &config_renderable_type)) {
+    if (!eglGetConfigAttrib(gl_display_->GetDisplay(), config_,
+                            EGL_RENDERABLE_TYPE, &config_renderable_type)) {
       LOG(ERROR) << "eglGetConfigAttrib failed with error "
                  << GetLastEGLErrorString();
       return false;
@@ -156,8 +158,7 @@
 
   // EGL_KHR_create_context allows requesting both a major and minor context
   // version
-  if (GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension(
-          "EGL_KHR_create_context")) {
+  if (gl_display_->HasEGLExtension("EGL_KHR_create_context")) {
     context_attributes.push_back(EGL_CONTEXT_MAJOR_VERSION);
     context_attributes.push_back(context_client_major_version);
 
@@ -175,8 +176,7 @@
 
   bool is_swangle = IsSoftwareGLImplementation(GetGLImplementationParts());
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextRobustnessSupported() ||
-      is_swangle) {
+  if (gl_display_->IsCreateContextRobustnessSupported() || is_swangle) {
     DVLOG(1) << "EGL_EXT_create_context_robustness supported.";
     context_attributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT);
     context_attributes.push_back(
@@ -186,8 +186,7 @@
           EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
       context_attributes.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT);
 
-      if (GLSurfaceEGL::GetGLDisplayEGL()
-              ->IsRobustnessVideoMemoryPurgeSupported()) {
+      if (gl_display_->IsRobustnessVideoMemoryPurgeSupported()) {
         context_attributes.push_back(
             EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV);
         context_attributes.push_back(EGL_TRUE);
@@ -205,8 +204,7 @@
     return false;
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()
-          ->IsCreateContextBindGeneratesResourceSupported()) {
+  if (gl_display_->IsCreateContextBindGeneratesResourceSupported()) {
     context_attributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM);
     context_attributes.push_back(attribs.bind_generates_resource ? EGL_TRUE
                                                                  : EGL_FALSE);
@@ -214,8 +212,7 @@
     DCHECK(attribs.bind_generates_resource);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()
-          ->IsCreateContextWebGLCompatabilitySupported()) {
+  if (gl_display_->IsCreateContextWebGLCompatabilitySupported()) {
     context_attributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE);
     context_attributes.push_back(
         attribs.webgl_compatibility_context ? EGL_TRUE : EGL_FALSE);
@@ -223,7 +220,7 @@
     DCHECK(!attribs.webgl_compatibility_context);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsEGLContextPrioritySupported()) {
+  if (gl_display_->IsEGLContextPrioritySupported()) {
     // Medium priority is the default, only set the attribute if
     // a different priority is requested.
     if (attribs.context_priority == ContextPriorityLow) {
@@ -237,7 +234,7 @@
     }
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsDisplayTextureShareGroupSupported()) {
+  if (gl_display_->IsDisplayTextureShareGroupSupported()) {
     context_attributes.push_back(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE);
     context_attributes.push_back(
         attribs.global_texture_share_group ? EGL_TRUE : EGL_FALSE);
@@ -245,8 +242,7 @@
     DCHECK(!attribs.global_texture_share_group);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()
-          ->IsDisplaySemaphoreShareGroupSupported()) {
+  if (gl_display_->IsDisplaySemaphoreShareGroupSupported()) {
     context_attributes.push_back(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE);
     context_attributes.push_back(
         attribs.global_semaphore_share_group ? EGL_TRUE : EGL_FALSE);
@@ -254,14 +250,13 @@
     DCHECK(!attribs.global_semaphore_share_group);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextClientArraysSupported()) {
+  if (gl_display_->IsCreateContextClientArraysSupported()) {
     // Disable client arrays if the context supports it
     context_attributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE);
     context_attributes.push_back(EGL_FALSE);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsRobustResourceInitSupported() ||
-      is_swangle) {
+  if (gl_display_->IsRobustResourceInitSupported() || is_swangle) {
     context_attributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
     context_attributes.push_back(
         (attribs.robust_resource_initialization || is_swangle) ? EGL_TRUE
@@ -270,7 +265,7 @@
     DCHECK(!attribs.robust_resource_initialization);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension(
+  if (gl_display_->HasEGLExtension(
           "EGL_ANGLE_create_context_backwards_compatible")) {
     // Request a specific context version. The Passthrough command decoder
     // relies on the returned context being the exact version it requested.
@@ -278,7 +273,7 @@
     context_attributes.push_back(EGL_FALSE);
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEPowerPreferenceSupported()) {
+  if (gl_display_->IsANGLEPowerPreferenceSupported()) {
     GpuPreference pref = attribs.gpu_preference;
     pref = GLSurface::AdjustGpuPreference(pref);
     switch (pref) {
@@ -298,8 +293,7 @@
     }
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()
-          ->IsANGLEExternalContextAndSurfaceSupported()) {
+  if (gl_display_->IsANGLEExternalContextAndSurfaceSupported()) {
     if (attribs.angle_create_from_external_context) {
       context_attributes.push_back(EGL_EXTERNAL_CONTEXT_ANGLE);
       context_attributes.push_back(EGL_TRUE);
@@ -310,8 +304,7 @@
     }
   }
 
-  if (GLSurfaceEGL::GetGLDisplayEGL()
-          ->IsANGLEContextVirtualizationSupported()) {
+  if (gl_display_->IsANGLEContextVirtualizationSupported()) {
     context_attributes.push_back(EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE);
     context_attributes.push_back(
         static_cast<EGLint>(attribs.angle_context_virtualization_group_number));
@@ -321,15 +314,15 @@
   context_attributes.push_back(EGL_NONE);
   context_attributes.push_back(EGL_NONE);
 
-  context_ = eglCreateContext(
-      display_, config_, share_group() ? share_group()->GetHandle() : nullptr,
-      context_attributes.data());
+  context_ =
+      eglCreateContext(gl_display_->GetDisplay(), config_,
+                       share_group() ? share_group()->GetHandle() : nullptr,
+                       context_attributes.data());
 
   // If EGL_KHR_no_config_context is in use and context creation failed,
   // it might indicate that an unsupported ES version was requested. Try
   // falling back to a lower version.
-  if (!context_ &&
-      GLSurfaceEGL::GetGLDisplayEGL()->IsEGLNoConfigContextSupported() &&
+  if (!context_ && gl_display_->IsEGLNoConfigContextSupported() &&
       eglGetError() == EGL_BAD_MATCH) {
     // Set up the list of versions to try: 3.1 -> 3.0 -> 2.0
     std::vector<std::pair<EGLint, EGLint>> candidate_versions;
@@ -351,7 +344,7 @@
       }
 
       context_ =
-          eglCreateContext(display_, config_,
+          eglCreateContext(gl_display_->GetDisplay(), config_,
                            share_group() ? share_group()->GetHandle() : nullptr,
                            context_attributes.data());
       // Stop searching as soon as a context is successfully created.
@@ -373,7 +366,7 @@
 void GLContextEGL::Destroy() {
   ReleaseYUVToRGBConvertersAndBackpressureFences();
   if (context_) {
-    if (!eglDestroyContext(display_, context_)) {
+    if (!eglDestroyContext(gl_display_->GetDisplay(), context_)) {
       LOG(ERROR) << "eglDestroyContext failed with error "
                  << GetLastEGLErrorString();
     }
@@ -388,7 +381,7 @@
   // contexts aren't supported since support for surfaceless EGL contexts is
   // required in order to properly release YUVToRGBConverter objects (see
   // GLContextEGL::ReleaseYUVToRGBConvertersAndBackpressureFences())
-  if (!GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported()) {
+  if (!gl_display_->IsEGLSurfacelessContextSupported()) {
     return nullptr;
   }
 
@@ -402,13 +395,13 @@
 }
 
 void GLContextEGL::SetVisibility(bool visibility) {
-  if (GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEPowerPreferenceSupported()) {
+  if (gl_display_->IsANGLEPowerPreferenceSupported()) {
     // It doesn't matter whether this context was explicitly allocated
     // with a power preference - ANGLE will take care of any default behavior.
     if (visibility) {
-      eglReacquireHighPowerGPUANGLE(display_, context_);
+      eglReacquireHighPowerGPUANGLE(gl_display_->GetDisplay(), context_);
     } else {
-      eglReleaseHighPowerGPUANGLE(display_, context_);
+      eglReleaseHighPowerGPUANGLE(gl_display_->GetDisplay(), context_);
     }
   }
 }
@@ -437,7 +430,8 @@
       // This call relies on the fact that yuv_to_rgb_converters_ are only ever
       // allocated in GLImageIOSurfaceEGL::CopyTexImage, which is only on
       // MacOS, where surfaceless EGL contexts are always supported.
-      if (!eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, context_)) {
+      if (!eglMakeCurrent(gl_display_->GetDisplay(), EGL_NO_SURFACE,
+                          EGL_NO_SURFACE, context_)) {
         LOG(ERROR) << "eglMakeCurrent failed with error "
                    << GetLastEGLErrorString();
       }
@@ -454,8 +448,8 @@
     }
 
     if (context_ != current_egl_context) {
-      if (!eglMakeCurrent(display_, current_draw_surface, current_read_surface,
-                          current_egl_context)) {
+      if (!eglMakeCurrent(gl_display_->GetDisplay(), current_draw_surface,
+                          current_read_surface, current_egl_context)) {
         LOG(ERROR) << "eglMakeCurrent failed with error "
                    << GetLastEGLErrorString();
       }
@@ -481,10 +475,8 @@
     glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   }
 
-  if (!eglMakeCurrent(display_,
-                      surface->GetHandle(),
-                      surface->GetHandle(),
-                      context_)) {
+  if (!eglMakeCurrent(gl_display_->GetDisplay(), surface->GetHandle(),
+                      surface->GetHandle(), context_)) {
     LOG(ERROR) << "eglMakeCurrent failed with error "
                << GetLastEGLErrorString();
     return false;
@@ -517,7 +509,7 @@
     glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
 
   SetCurrent(nullptr);
-  if (!eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
+  if (!eglMakeCurrent(gl_display_->GetDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
                       EGL_NO_CONTEXT)) {
     LOG(ERROR) << "eglMakeCurrent failed to release current with error "
                << GetLastEGLErrorString();
@@ -559,7 +551,7 @@
   DCHECK(g_current_gl_driver);
   const ExtensionsGL& ext = g_current_gl_driver->ext;
   if ((graphics_reset_status_ == GL_NO_ERROR) &&
-      GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextRobustnessSupported() &&
+      gl_display_->IsCreateContextRobustnessSupported() &&
       (ext.b_GL_KHR_robustness || ext.b_GL_EXT_robustness ||
        ext.b_GL_ARB_robustness)) {
     graphics_reset_status_ = glGetGraphicsResetStatusARB();
diff --git a/ui/gl/gl_context_egl.h b/ui/gl/gl_context_egl.h
index 142d179a8..52ed0cf3 100644
--- a/ui/gl/gl_context_egl.h
+++ b/ui/gl/gl_context_egl.h
@@ -11,11 +11,10 @@
 #include "ui/gl/gl_export.h"
 
 typedef void* EGLContext;
-typedef void* EGLDisplay;
 typedef void* EGLConfig;
 
 namespace gl {
-
+class GLDisplayEGL;
 class GLSurface;
 
 // Encapsulates an EGL OpenGL ES context.
@@ -47,7 +46,7 @@
   void ReleaseYUVToRGBConvertersAndBackpressureFences();
 
   EGLContext context_ = nullptr;
-  EGLDisplay display_ = nullptr;
+  GLDisplayEGL* gl_display_ = nullptr;
   EGLConfig config_ = nullptr;
   unsigned int graphics_reset_status_ = 0;  // GL_NO_ERROR;
   bool unbind_fbo_on_makecurrent_ = false;
diff --git a/ui/gl/gl_image_d3d_unittest.cc b/ui/gl/gl_image_d3d_unittest.cc
index 7b924d70..d0936ce 100644
--- a/ui/gl/gl_image_d3d_unittest.cc
+++ b/ui/gl/gl_image_d3d_unittest.cc
@@ -31,7 +31,7 @@
         GLImplementationParts(ANGLEImplementation::kD3D11));
   }
 
-  bool SkipTest() const override { return !d3d11_device_; }
+  bool SkipTest(GLDisplay*) const override { return !d3d11_device_; }
 
   scoped_refptr<GLImageD3D> CreateImage(const gfx::Size& size) const {
     D3D11_TEXTURE2D_DESC desc;
diff --git a/ui/gl/gl_image_native_pixmap_unittest.cc b/ui/gl/gl_image_native_pixmap_unittest.cc
index 2941b08..ebff0df 100644
--- a/ui/gl/gl_image_native_pixmap_unittest.cc
+++ b/ui/gl/gl_image_native_pixmap_unittest.cc
@@ -43,9 +43,10 @@
 #endif
   }
 
-  bool SkipTest() const override {
+  bool SkipTest(GLDisplay* display) const override {
     const std::string dmabuf_import_ext = "EGL_MESA_image_dma_buf_export";
-    std::string platform_extensions(DriverEGL::GetPlatformExtensions());
+    std::string platform_extensions(ExtensionsEGL::GetPlatformExtensions(
+        static_cast<GLDisplayEGL*>(display)));
     gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
     if (!gfx::HasExtension(extensions, dmabuf_import_ext)) {
       LOG(WARNING) << "Skip test, missing extension " << dmabuf_import_ext;
@@ -95,7 +96,7 @@
 
 TYPED_TEST_P_WITH_EXPANSION(GLImageNativePixmapToDmabufTest,
                             MAYBE_GLTexture2DToDmabuf) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   const gfx::Size image_size(64, 64);
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index a70c69a..930c8f6 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -998,14 +998,14 @@
       GLDisplayManagerEGL::GetInstance()->GetDisplay(system_device_id);
   if (display->GetDisplay() == EGL_NO_DISPLAY) {
     // Must be called before InitializeDisplay().
-    g_driver_egl.InitializeClientExtensionBindings();
+    g_driver_egl.ext.InitializeClientExtensionSettings();
 
     display = InitializeDisplay(native_display, system_device_id);
     if (display->GetDisplay() == EGL_NO_DISPLAY)
       return nullptr;
 
     // Must be called after InitializeDisplay().
-    g_driver_egl.InitializeExtensionBindings();
+    g_driver_egl.ext.InitializeExtensionSettings(display);
 
     InitializeOneOffCommon(display);
   }
@@ -1014,11 +1014,11 @@
 
 // static
 GLDisplayEGL* GLSurfaceEGL::InitializeOneOffForTesting() {
-  g_driver_egl.InitializeClientExtensionBindings();
+  g_driver_egl.ext.InitializeClientExtensionSettings();
   GLDisplayEGL* display =
       GLDisplayManagerEGL::GetInstance()->GetDisplay(GpuPreference::kDefault);
   display->SetDisplay(eglGetCurrentDisplay());
-  g_driver_egl.InitializeExtensionBindings();
+  g_driver_egl.ext.InitializeExtensionSettings(display);
   InitializeOneOffCommon(display);
   return display;
 }
@@ -1170,7 +1170,7 @@
   DCHECK(display);
   if (display->GetDisplay() == EGL_NO_DISPLAY)
     return false;
-  g_driver_egl.UpdateConditionalExtensionBindings();
+  g_driver_egl.ext.UpdateConditionalExtensionSettings(display);
   display->egl_client_extensions =
       eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
   display->egl_extensions =
diff --git a/ui/gl/test/gl_image_bind_test_template.h b/ui/gl/test/gl_image_bind_test_template.h
index 43c5f37..8a536b9 100644
--- a/ui/gl/test/gl_image_bind_test_template.h
+++ b/ui/gl/test/gl_image_bind_test_template.h
@@ -15,7 +15,7 @@
 TYPED_TEST_SUITE_P(GLImageBindTest);
 
 TYPED_TEST_P(GLImageBindTest, BindTexImage) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   const gfx::Size image_size(256, 256);
diff --git a/ui/gl/test/gl_image_test_support.cc b/ui/gl/test/gl_image_test_support.cc
index 81b85cf4..58505c30 100644
--- a/ui/gl/test/gl_image_test_support.cc
+++ b/ui/gl/test/gl_image_test_support.cc
@@ -33,10 +33,8 @@
 }
 }  // namespace
 
-GLDisplay* GLImageTestSupport::display_ = nullptr;
-
 // static
-void GLImageTestSupport::InitializeGL(
+GLDisplay* GLImageTestSupport::InitializeGL(
     absl::optional<GLImplementationParts> prefered_impl) {
 #if defined(USE_OZONE)
   ui::OzonePlatform::InitParams params;
@@ -52,17 +50,19 @@
       prefered_impl ? *prefered_impl : allowed_impls[0];
   DCHECK(impl.IsAllowed(allowed_impls));
 
-  display_ = GLSurfaceTestSupport::InitializeOneOffImplementation(impl, true);
+  GLDisplay* display =
+      GLSurfaceTestSupport::InitializeOneOffImplementation(impl, true);
 #if defined(USE_OZONE)
   // Make sure all the tasks posted to the current task runner by the
   // initialization functions are run before running the tests.
   base::RunLoop().RunUntilIdle();
 #endif
+  return display;
 }
 
 // static
-void GLImageTestSupport::CleanupGL() {
-  GLSurfaceTestSupport::ShutdownGL(display_);
+void GLImageTestSupport::CleanupGL(GLDisplay* display) {
+  GLSurfaceTestSupport::ShutdownGL(display);
 }
 
 // static
@@ -286,5 +286,4 @@
   }
   NOTREACHED();
 }
-
 }  // namespace gl
diff --git a/ui/gl/test/gl_image_test_support.h b/ui/gl/test/gl_image_test_support.h
index 393872f..d1e0707 100644
--- a/ui/gl/test/gl_image_test_support.h
+++ b/ui/gl/test/gl_image_test_support.h
@@ -9,20 +9,21 @@
 
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/buffer_types.h"
-#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_implementation.h"
 
 namespace gl {
+class GLDisplay;
 
 class GLImageTestSupport {
  public:
   // Initialize GL for image testing. |prefered_impl| is the GL implementation
   // to select if it is an allowed GL implementation. Otherwise it selects the
   // first allowed GL implementation.
-  static void InitializeGL(absl::optional<GLImplementationParts> prefered_impl);
+  static GLDisplay* InitializeGL(
+      absl::optional<GLImplementationParts> prefered_impl);
 
   // Cleanup GL after being initialized for image testing.
-  static void CleanupGL();
+  static void CleanupGL(GLDisplay* display);
 
   // Initialize buffer of a specific |format| to |color|.
   static void SetBufferDataToColor(int width,
@@ -32,9 +33,6 @@
                                    gfx::BufferFormat format,
                                    const uint8_t color[4],
                                    uint8_t* data);
-
- private:
-  static GLDisplay* display_;
 };
 
 }  // namespace gl
diff --git a/ui/gl/test/gl_image_test_template.cc b/ui/gl/test/gl_image_test_template.cc
index 5135f8d..5188372 100644
--- a/ui/gl/test/gl_image_test_template.cc
+++ b/ui/gl/test/gl_image_test_template.cc
@@ -143,7 +143,7 @@
   return absl::nullopt;
 }
 
-bool GLImageTestDelegateBase::SkipTest() const {
+bool GLImageTestDelegateBase::SkipTest(GLDisplay*) const {
   return false;
 }
 
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h
index 8012637..f0b53a3 100644
--- a/ui/gl/test/gl_image_test_template.h
+++ b/ui/gl/test/gl_image_test_template.h
@@ -20,6 +20,7 @@
 #include "ui/gfx/buffer_types.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_helper.h"
 #include "ui/gl/gl_image.h"
 #include "ui/gl/gl_surface.h"
@@ -63,7 +64,7 @@
 
   virtual absl::optional<GLImplementationParts> GetPreferedGLImplementation()
       const;
-  virtual bool SkipTest() const;
+  virtual bool SkipTest(GLDisplay* display) const;
 };
 
 template <typename GLImageTestDelegate>
@@ -72,7 +73,7 @@
   // Overridden from testing::Test:
   void SetUp() override {
     auto prefered_impl = delegate_.GetPreferedGLImplementation();
-    GLImageTestSupport::InitializeGL(prefered_impl);
+    display_ = GLImageTestSupport::InitializeGL(prefered_impl);
     surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
     context_ =
         gl::init::CreateGLContext(nullptr, surface_.get(), GLContextAttribs());
@@ -84,19 +85,20 @@
     context_->ReleaseCurrent(surface_.get());
     context_ = nullptr;
     surface_ = nullptr;
-    GLImageTestSupport::CleanupGL();
+    GLImageTestSupport::CleanupGL(display_);
   }
 
  protected:
   scoped_refptr<GLSurface> surface_;
   scoped_refptr<GLContext> context_;
   GLImageTestDelegate delegate_;
+  GLDisplay* display_ = nullptr;
 };
 
 TYPED_TEST_SUITE_P(GLImageTest);
 
 TYPED_TEST_P_WITH_EXPANSION(GLImageTest, MAYBE_Create) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   // NOTE: On some drm devices (mediatek) the mininum width/height to add an fb
@@ -133,7 +135,7 @@
 TYPED_TEST_SUITE_P(GLImageOddSizeTest);
 
 TYPED_TEST_P_WITH_EXPANSION(GLImageOddSizeTest, MAYBE_Create) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   const gfx::Size odd_image_size(17, 53);
@@ -159,7 +161,7 @@
 TYPED_TEST_SUITE_P(GLImageCopyTest);
 
 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   // CopyTexImage follows different code paths depending whether the image is
diff --git a/ui/gl/test/gl_image_zero_initialize_test_template.h b/ui/gl/test/gl_image_zero_initialize_test_template.h
index 01996092..3318a444 100644
--- a/ui/gl/test/gl_image_zero_initialize_test_template.h
+++ b/ui/gl/test/gl_image_zero_initialize_test_template.h
@@ -18,7 +18,7 @@
 TYPED_TEST_SUITE_P(GLImageZeroInitializeTest);
 
 TYPED_TEST_P(GLImageZeroInitializeTest, ZeroInitialize) {
-  if (this->delegate_.SkipTest())
+  if (this->delegate_.SkipTest(this->display_))
     return;
 
   const gfx::Size image_size(256, 256);
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index 3384dbf..53d3b18 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -141,24 +141,15 @@
     // Default to null platform
     native_display_ = gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
 
-    gl::g_driver_egl.InitializeClientExtensionBindings();
-
-    const char* client_extensions_string =
-        eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
-
-    gfx::ExtensionSet client_extensions =
-        client_extensions_string
-            ? gfx::MakeExtensionSet(client_extensions_string)
-            : gfx::ExtensionSet();
-
-    if (gfx::HasExtension(client_extensions, "EGL_MESA_platform_surfaceless")) {
+    gl::g_driver_egl.ext.InitializeClientExtensionSettings();
+    if (gl::g_driver_egl.ext.b_EGL_MESA_platform_surfaceless) {
       native_display_ = gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY,
                                                EGL_PLATFORM_SURFACELESS_MESA);
     }
 
-    if (!(gfx::HasExtension(client_extensions, "EGL_EXT_device_query") &&
-          gfx::HasExtension(client_extensions, "EGL_EXT_platform_device") &&
-          gfx::HasExtension(client_extensions, "EGL_EXT_device_enumeration"))) {
+    if (!(gl::g_driver_egl.ext.b_EGL_EXT_device_query &&
+          gl::g_driver_egl.ext.b_EGL_EXT_platform_device &&
+          gl::g_driver_egl.ext.b_EGL_EXT_device_enumeration)) {
       LOG(WARNING) << "Platform device extensions not found.";
       return native_display_;
     }
diff --git a/ui/views/accessibility/ax_virtual_view.cc b/ui/views/accessibility/ax_virtual_view.cc
index c9c35398..ec6716cd 100644
--- a/ui/views/accessibility/ax_virtual_view.cc
+++ b/ui/views/accessibility/ax_virtual_view.cc
@@ -77,11 +77,11 @@
   DCHECK(view);
   if (view->virtual_parent_view_ == this)
     return;  // Already a child of this virtual view.
-  AddChildViewAt(std::move(view), static_cast<int>(children_.size()));
+  AddChildViewAt(std::move(view), children_.size());
 }
 
 void AXVirtualView::AddChildViewAt(std::unique_ptr<AXVirtualView> view,
-                                   int index) {
+                                   size_t index) {
   DCHECK(view);
   CHECK_NE(view.get(), this)
       << "You cannot add an AXVirtualView as its own child.";
@@ -90,8 +90,7 @@
   DCHECK(!view->virtual_parent_view_) << "This |view| already has an "
                                          "AXVirtualView parent. Call "
                                          "RemoveChildView first.";
-  DCHECK_GE(index, 0);
-  DCHECK_LE(index, static_cast<int>(children_.size()));
+  DCHECK_LE(index, children_.size());
 
   view->virtual_parent_view_ = this;
   children_.insert(children_.begin() + index, std::move(view));
@@ -101,23 +100,21 @@
   }
 }
 
-void AXVirtualView::ReorderChildView(AXVirtualView* view, int index) {
+void AXVirtualView::ReorderChildView(AXVirtualView* view, size_t index) {
   DCHECK(view);
-  if (index >= static_cast<int>(children_.size()))
-    return;
-  if (index < 0)
-    index = static_cast<int>(children_.size()) - 1;
+  index = std::min(index, children_.size() - 1);
 
   DCHECK_EQ(view->virtual_parent_view_, this);
   if (children_[index].get() == view)
     return;
 
-  int cur_index = GetIndexOf(view);
-  if (cur_index < 0)
+  auto cur_index = GetIndexOf(view);
+  if (!cur_index.has_value())
     return;
 
-  std::unique_ptr<AXVirtualView> child = std::move(children_[cur_index]);
-  children_.erase(children_.begin() + cur_index);
+  std::unique_ptr<AXVirtualView> child =
+      std::move(children_[cur_index.value()]);
+  children_.erase(children_.begin() + cur_index.value());
   children_.insert(children_.begin() + index, std::move(child));
 
   GetOwnerView()->NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged,
@@ -139,8 +136,8 @@
 std::unique_ptr<AXVirtualView> AXVirtualView::RemoveChildView(
     AXVirtualView* view) {
   DCHECK(view);
-  int cur_index = GetIndexOf(view);
-  if (cur_index < 0)
+  auto cur_index = GetIndexOf(view);
+  if (!cur_index.has_value())
     return {};
 
   bool focus_changed = false;
@@ -153,8 +150,9 @@
     }
   }
 
-  std::unique_ptr<AXVirtualView> child = std::move(children_[cur_index]);
-  children_.erase(children_.begin() + cur_index);
+  std::unique_ptr<AXVirtualView> child =
+      std::move(children_[cur_index.value()]);
+  children_.erase(children_.begin() + cur_index.value());
   child->virtual_parent_view_ = nullptr;
   child->populate_data_callback_.Reset();
 
@@ -182,13 +180,15 @@
   return false;
 }
 
-int AXVirtualView::GetIndexOf(const AXVirtualView* view) const {
+absl::optional<size_t> AXVirtualView::GetIndexOf(
+    const AXVirtualView* view) const {
   DCHECK(view);
   const auto iter =
       std::find_if(children_.begin(), children_.end(),
                    [view](const auto& child) { return child.get() == view; });
-  return iter != children_.end() ? static_cast<int>(iter - children_.begin())
-                                 : -1;
+  return iter != children_.end() ? absl::make_optional(static_cast<size_t>(
+                                       iter - children_.begin()))
+                                 : absl::nullopt;
 }
 
 const char* AXVirtualView::GetViewClassName() const {
diff --git a/ui/views/accessibility/ax_virtual_view.h b/ui/views/accessibility/ax_virtual_view.h
index 52f3e64..b081aa0 100644
--- a/ui/views/accessibility/ax_virtual_view.h
+++ b/ui/views/accessibility/ax_virtual_view.h
@@ -13,6 +13,7 @@
 #include "base/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/ax_enums.mojom-forward.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
@@ -71,11 +72,11 @@
   // Adds |view| as a child of this virtual view, optionally at |index|.
   // We take ownership of our children.
   void AddChildView(std::unique_ptr<AXVirtualView> view);
-  void AddChildViewAt(std::unique_ptr<AXVirtualView> view, int index);
+  void AddChildViewAt(std::unique_ptr<AXVirtualView> view, size_t index);
 
-  // Moves |view| to the specified |index|. A negative value for |index| moves
+  // Moves |view| to the specified |index|. A too-large value for |index| moves
   // |view| to the end.
-  void ReorderChildView(AXVirtualView* view, int index);
+  void ReorderChildView(AXVirtualView* view, size_t index);
 
   // Removes this virtual view from its parent, which could either be a virtual
   // or a real view. Hands ownership of this view back to the caller.
@@ -110,9 +111,9 @@
   // is also this AXVirtualView.
   bool Contains(const AXVirtualView* view) const;
 
-  // Returns the index of |view|, or -1 if |view| is not a child of this virtual
-  // view.
-  int GetIndexOf(const AXVirtualView* view) const;
+  // Returns the index of |view|, or nullopt if |view| is not a child of this
+  // virtual view.
+  absl::optional<size_t> GetIndexOf(const AXVirtualView* view) const;
 
   //
   // Other methods.
diff --git a/ui/views/accessibility/ax_virtual_view_unittest.cc b/ui/views/accessibility/ax_virtual_view_unittest.cc
index 3048b9a..1f433b8f 100644
--- a/ui/views/accessibility/ax_virtual_view_unittest.cc
+++ b/ui/views/accessibility/ax_virtual_view_unittest.cc
@@ -293,7 +293,7 @@
   virtual_label_->AddChildView(base::WrapUnique(virtual_child_2));
   ASSERT_EQ(2, virtual_label_->GetChildCount());
 
-  virtual_label_->ReorderChildView(virtual_child_1, -1);
+  virtual_label_->ReorderChildView(virtual_child_1, 100);
   ASSERT_EQ(2, virtual_label_->GetChildCount());
   EXPECT_EQ(virtual_label_->GetNativeObject(), virtual_child_2->GetParent());
   ASSERT_NE(nullptr, virtual_label_->ChildAtIndex(0));
@@ -363,11 +363,11 @@
   virtual_child_2->AddChildView(base::WrapUnique(virtual_child_3));
   ASSERT_EQ(1, virtual_child_2->GetChildCount());
 
-  EXPECT_EQ(-1, virtual_label_->GetIndexOf(virtual_label_));
-  EXPECT_EQ(0, virtual_label_->GetIndexOf(virtual_child_1));
-  EXPECT_EQ(1, virtual_label_->GetIndexOf(virtual_child_2));
-  EXPECT_EQ(-1, virtual_label_->GetIndexOf(virtual_child_3));
-  EXPECT_EQ(0, virtual_child_2->GetIndexOf(virtual_child_3));
+  EXPECT_FALSE(virtual_label_->GetIndexOf(virtual_label_).has_value());
+  EXPECT_EQ(0u, virtual_label_->GetIndexOf(virtual_child_1).value());
+  EXPECT_EQ(1u, virtual_label_->GetIndexOf(virtual_child_2).value());
+  EXPECT_FALSE(virtual_label_->GetIndexOf(virtual_child_3).has_value());
+  EXPECT_EQ(0u, virtual_child_2->GetIndexOf(virtual_child_3).value());
 
   virtual_label_->RemoveAllChildViews();
   ASSERT_EQ(0, virtual_label_->GetChildCount());
diff --git a/ui/views/accessibility/view_accessibility.cc b/ui/views/accessibility/view_accessibility.cc
index 442c77b..f3bfa48 100644
--- a/ui/views/accessibility/view_accessibility.cc
+++ b/ui/views/accessibility/view_accessibility.cc
@@ -82,16 +82,14 @@
 
 void ViewAccessibility::AddVirtualChildView(
     std::unique_ptr<AXVirtualView> virtual_view) {
-  AddVirtualChildViewAt(std::move(virtual_view),
-                        static_cast<int>(virtual_children_.size()));
+  AddVirtualChildViewAt(std::move(virtual_view), virtual_children_.size());
 }
 
 void ViewAccessibility::AddVirtualChildViewAt(
     std::unique_ptr<AXVirtualView> virtual_view,
-    int index) {
+    size_t index) {
   DCHECK(virtual_view);
-  DCHECK_GE(index, 0);
-  DCHECK_LE(static_cast<size_t>(index), virtual_children_.size());
+  DCHECK_LE(index, virtual_children_.size());
 
   if (virtual_view->parent_view() == this)
     return;
@@ -109,13 +107,13 @@
 std::unique_ptr<AXVirtualView> ViewAccessibility::RemoveVirtualChildView(
     AXVirtualView* virtual_view) {
   DCHECK(virtual_view);
-  int cur_index = GetIndexOf(virtual_view);
-  if (cur_index < 0)
+  auto cur_index = GetIndexOf(virtual_view);
+  if (!cur_index.has_value())
     return {};
 
   std::unique_ptr<AXVirtualView> child =
-      std::move(virtual_children_[cur_index]);
-  virtual_children_.erase(virtual_children_.begin() + cur_index);
+      std::move(virtual_children_[cur_index.value()]);
+  virtual_children_.erase(virtual_children_.begin() + cur_index.value());
   child->set_parent_view(nullptr);
   child->UnsetPopulateDataCallback();
   if (focused_virtual_child_ && child->Contains(focused_virtual_child_))
@@ -139,7 +137,8 @@
   return false;
 }
 
-int ViewAccessibility::GetIndexOf(const AXVirtualView* virtual_view) const {
+absl::optional<size_t> ViewAccessibility::GetIndexOf(
+    const AXVirtualView* virtual_view) const {
   DCHECK(virtual_view);
   const auto iter =
       std::find_if(virtual_children_.begin(), virtual_children_.end(),
@@ -147,8 +146,9 @@
                      return child.get() == virtual_view;
                    });
   return iter != virtual_children_.end()
-             ? static_cast<int>(iter - virtual_children_.begin())
-             : -1;
+             ? absl::make_optional(
+                   static_cast<size_t>(iter - virtual_children_.begin()))
+             : absl::nullopt;
 }
 
 void ViewAccessibility::GetAccessibleNodeData(ui::AXNodeData* data) const {
diff --git a/ui/views/accessibility/view_accessibility.h b/ui/views/accessibility/view_accessibility.h
index 9b8cfcf..a41f431 100644
--- a/ui/views/accessibility/view_accessibility.h
+++ b/ui/views/accessibility/view_accessibility.h
@@ -199,7 +199,7 @@
   // Adds |virtual_view| as a child of this View at an index.
   // We take ownership of our virtual children.
   void AddVirtualChildViewAt(std::unique_ptr<AXVirtualView> virtual_view,
-                             int index);
+                             size_t index);
 
   // Removes |virtual_view| from this View. The virtual view's parent will
   // change to nullptr. Hands ownership back to the caller.
@@ -216,9 +216,9 @@
   // View, even as an indirect descendant.
   bool Contains(const AXVirtualView* virtual_view) const;
 
-  // Returns the index of |virtual_view|, or -1 if |virtual_view| is not a child
-  // of this View.
-  int GetIndexOf(const AXVirtualView* virtual_view) const;
+  // Returns the index of |virtual_view|, or nullopt if |virtual_view| is not a
+  // child of this View.
+  absl::optional<size_t> GetIndexOf(const AXVirtualView* virtual_view) const;
 
   // Returns the native accessibility object associated with the AXVirtualView
   // descendant that is currently focused. If no virtual descendants are
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc
index 85f6a37..9a8e5d5 100644
--- a/ui/views/accessibility/view_ax_platform_node_delegate.cc
+++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -771,9 +771,10 @@
   if (found_view == views_in_group.end())
     return absl::nullopt;
 
-  int posInSet = std::distance(views_in_group.begin(), found_view);
-  // posInSet is zero-based; users expect one-based, so increment.
-  return ++posInSet;
+  int pos_in_set = base::checked_cast<int>(
+      std::distance(views_in_group.begin(), found_view));
+  // pos_in_set is zero-based; users expect one-based, so increment.
+  return ++pos_in_set;
 }
 
 absl::optional<int> ViewAXPlatformNodeDelegate::GetSetSize() const {
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc
index e98dd55f..266c7a9 100644
--- a/ui/views/controls/table/table_view.cc
+++ b/ui/views/controls/table/table_view.cc
@@ -1526,11 +1526,11 @@
 
 void TableView::PopulateAccessibilityRowData(AXVirtualView* ax_row,
                                              ui::AXNodeData* data) {
-  int ax_index = GetViewAccessibility().GetIndexOf(ax_row);
-  DCHECK_GE(ax_index, 0);
+  auto ax_index = GetViewAccessibility().GetIndexOf(ax_row);
+  DCHECK(ax_index.has_value());
 
-  int row_index = ax_index - (header_ ? 1 : 0);
-  int model_index = ViewToModel(row_index);
+  size_t row_index = ax_index.value() - (header_ ? 1 : 0);
+  int model_index = ViewToModel(static_cast<int>(row_index));
   DCHECK_GE(model_index, 0);
 
   // When navigating using up / down cursor keys on the Mac, we read the
@@ -1553,23 +1553,23 @@
   AXVirtualView* ax_row = ax_cell->virtual_parent_view();
   DCHECK(ax_row);
 
-  int ax_index = GetViewAccessibility().GetIndexOf(ax_row);
-  DCHECK_GE(ax_index, 0);
+  auto ax_index = GetViewAccessibility().GetIndexOf(ax_row);
+  DCHECK(ax_index.has_value());
 
-  int row_index = ax_index - (header_ ? 1 : 0);
-  int column_index = ax_row->GetIndexOf(ax_cell);
-  DCHECK_GE(column_index, 0);
+  size_t row_index = ax_index.value() - (header_ ? 1 : 0);
+  auto column_index = ax_row->GetIndexOf(ax_cell);
+  DCHECK(column_index.has_value());
 
-  int model_index = ViewToModel(row_index);
+  int model_index = ViewToModel(static_cast<int>(row_index));
   DCHECK_GE(model_index, 0);
 
-  gfx::Rect cell_bounds = GetCellBounds(row_index, column_index);
+  gfx::Rect cell_bounds = GetCellBounds(row_index, column_index.value());
 
   if (!GetVisibleBounds().Intersects(cell_bounds))
     data->AddState(ax::mojom::State::kInvisible);
 
   if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell &&
-      static_cast<const int>(column_index) == GetActiveVisibleColumnIndex()) {
+      static_cast<int>(column_index.value()) == GetActiveVisibleColumnIndex()) {
     if (selection_model().IsSelected(model_index))
       data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
   }
@@ -1577,8 +1577,8 @@
   // Set the cell's value since it changes dynamically.
   std::u16string current_name = base::UTF8ToUTF16(
       data->GetStringAttribute(ax::mojom::StringAttribute::kName));
-  std::u16string new_name =
-      model()->GetText(model_index, GetVisibleColumn(column_index).column.id);
+  std::u16string new_name = model()->GetText(
+      model_index, GetVisibleColumn(column_index.value()).column.id);
   data->SetName(new_name);
   if (current_name != new_name) {
     ui::AXNodeData& cell_data = ax_cell->GetCustomData();
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc
index bdbc451..263321af 100644
--- a/ui/views/controls/tree/tree_view.cc
+++ b/ui/views/controls/tree/tree_view.cc
@@ -539,8 +539,7 @@
     parent_node->Add(std::move(child), i);
     DCHECK_LE(static_cast<int>(i),
               parent_node->accessibility_view()->GetChildCount());
-    parent_node->accessibility_view()->AddChildViewAt(std::move(ax_view),
-                                                      static_cast<int>(i));
+    parent_node->accessibility_view()->AddChildViewAt(std::move(ax_view), i);
   }
   if (IsExpanded(parent)) {
     NotifyAccessibilityEvent(ax::mojom::Event::kRowCountChanged, true);
@@ -1229,8 +1228,8 @@
   DCHECK(parent_internal_node->loaded_children());
   AXVirtualView* parent_ax_view = parent_internal_node->accessibility_view();
   DCHECK(parent_ax_view);
-  size_t index = parent_ax_view->GetIndexOf(ax_view);
-  return parent_internal_node->children()[index].get();
+  auto index = parent_ax_view->GetIndexOf(ax_view);
+  return parent_internal_node->children()[index.value()].get();
 }
 
 gfx::Rect TreeView::GetBoundsForNode(InternalNode* node) {
diff --git a/ui/views/controls/tree/tree_view_unittest.cc b/ui/views/controls/tree/tree_view_unittest.cc
index 84692d9..20ff974 100644
--- a/ui/views/controls/tree/tree_view_unittest.cc
+++ b/ui/views/controls/tree/tree_view_unittest.cc
@@ -239,7 +239,7 @@
     const AXVirtualView* parent_view = ax_view->virtual_parent_view();
     while (parent_view) {
       size_t sibling_index_in_parent =
-          static_cast<size_t>(parent_view->GetIndexOf(ax_view)) + 1;
+          parent_view->GetIndexOf(ax_view).value() + 1;
       if (sibling_index_in_parent < parent_view->children().size()) {
         ax_view = parent_view->children()[sibling_index_in_parent].get();
         break;
@@ -313,7 +313,7 @@
     const AXVirtualView* parent_view = ax_view->virtual_parent_view();
     while (parent_view) {
       size_t sibling_index_in_parent =
-          static_cast<size_t>(parent_view->GetIndexOf(ax_view)) + 1;
+          parent_view->GetIndexOf(ax_view).value() + 1;
       if (sibling_index_in_parent < parent_view->children().size()) {
         ax_view = parent_view->children()[sibling_index_in_parent].get();
         break;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 85c878b..e57049c 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -374,9 +374,11 @@
   host_->window()->RemovePreTargetHandler(root_window_event_filter_.get());
 
   host_->RemoveObserver(this);
-  host_.reset();
   // WindowEventDispatcher owns |desktop_window_tree_host_|.
   desktop_window_tree_host_ = nullptr;
+  // Delete host after resetting `desktop_window_tree_host_` and
+  // `content_window_` to avoid accessing the stale instance during deletion.
+  host_.reset();
   content_window_ = nullptr;
 
   // |OnNativeWidgetDestroyed| may delete |this| if the object does not own
@@ -769,7 +771,7 @@
 
 bool DesktopNativeWidgetAura::HasCapture() const {
   return content_window_ && content_window_->HasCapture() &&
-         desktop_window_tree_host_->HasCapture();
+         desktop_window_tree_host_ && desktop_window_tree_host_->HasCapture();
 }
 
 ui::InputMethod* DesktopNativeWidgetAura::GetInputMethod() {
@@ -777,30 +779,31 @@
 }
 
 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->CenterWindow(size);
 }
 
 void DesktopNativeWidgetAura::GetWindowPlacement(
     gfx::Rect* bounds,
     ui::WindowShowState* maximized) const {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->GetWindowPlacement(bounds, maximized);
 }
 
 bool DesktopNativeWidgetAura::SetWindowTitle(const std::u16string& title) {
-  if (!content_window_)
+  if (!desktop_window_tree_host_)
     return false;
   return desktop_window_tree_host_->SetWindowTitle(title);
 }
 
 void DesktopNativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
                                              const gfx::ImageSkia& app_icon) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetWindowIcons(window_icon, app_icon);
 
-  NativeWidgetAura::AssignIconToAuraWindow(content_window_, window_icon,
-                                           app_icon);
+  if (content_window_)
+    NativeWidgetAura::AssignIconToAuraWindow(content_window_, window_icon,
+                                             app_icon);
 }
 
 const gfx::ImageSkia* DesktopNativeWidgetAura::GetWindowIcon() {
@@ -819,28 +822,30 @@
 }
 
 gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
-  return content_window_ ? desktop_window_tree_host_->GetWindowBoundsInScreen()
-                         : gfx::Rect();
+  return desktop_window_tree_host_
+             ? desktop_window_tree_host_->GetWindowBoundsInScreen()
+             : gfx::Rect();
 }
 
 gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
-  return content_window_
+  return desktop_window_tree_host_
              ? desktop_window_tree_host_->GetClientAreaBoundsInScreen()
              : gfx::Rect();
 }
 
 gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
-  return content_window_ ? desktop_window_tree_host_->GetRestoredBounds()
-                         : gfx::Rect();
+  return desktop_window_tree_host_
+             ? desktop_window_tree_host_->GetRestoredBounds()
+             : gfx::Rect();
 }
 
 std::string DesktopNativeWidgetAura::GetWorkspace() const {
-  return content_window_ ? desktop_window_tree_host_->GetWorkspace()
-                         : std::string();
+  return desktop_window_tree_host_ ? desktop_window_tree_host_->GetWorkspace()
+                                   : std::string();
 }
 
 void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
-  if (!content_window_)
+  if (!desktop_window_tree_host_)
     return;
   desktop_window_tree_host_->SetBoundsInDIP(bounds);
 }
@@ -852,49 +857,49 @@
 }
 
 void DesktopNativeWidgetAura::SetSize(const gfx::Size& size) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetSize(size);
 }
 
 void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->StackAbove(native_view);
 }
 
 void DesktopNativeWidgetAura::StackAtTop() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->StackAtTop();
 }
 
 void DesktopNativeWidgetAura::SetShape(
     std::unique_ptr<Widget::ShapeRects> shape) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetShape(std::move(shape));
 }
 
 void DesktopNativeWidgetAura::Close() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->Close();
 }
 
 void DesktopNativeWidgetAura::CloseNow() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->CloseNow();
 }
 
 void DesktopNativeWidgetAura::Show(ui::WindowShowState show_state,
                                    const gfx::Rect& restore_bounds) {
-  if (!content_window_)
+  if (!desktop_window_tree_host_)
     return;
 
   desktop_window_tree_host_->Show(show_state, restore_bounds);
 }
 
 void DesktopNativeWidgetAura::Hide() {
-  if (!content_window_)
-    return;
-  desktop_window_tree_host_->AsWindowTreeHost()->Hide();
-  content_window_->Hide();
+  if (desktop_window_tree_host_)
+    desktop_window_tree_host_->AsWindowTreeHost()->Hide();
+  if (content_window_)
+    content_window_->Hide();
 }
 
 bool DesktopNativeWidgetAura::IsVisible() const {
@@ -904,11 +909,11 @@
   // aren't fully visible as we haven't shown the content window. Callers may
   // short-circuit a call to show this widget if they think its already visible.
   return content_window_ && content_window_->TargetVisibility() &&
-         desktop_window_tree_host_->IsVisible();
+         desktop_window_tree_host_ && desktop_window_tree_host_->IsVisible();
 }
 
 void DesktopNativeWidgetAura::Activate() {
-  if (content_window_) {
+  if (desktop_window_tree_host_ && content_window_) {
     bool was_tree_active = desktop_window_tree_host_->IsActive();
     desktop_window_tree_host_->Activate();
 
@@ -925,12 +930,13 @@
 }
 
 void DesktopNativeWidgetAura::Deactivate() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->Deactivate();
 }
 
 bool DesktopNativeWidgetAura::IsActive() const {
-  return content_window_ && desktop_window_tree_host_->IsActive() &&
+  return content_window_ && desktop_window_tree_host_ &&
+         desktop_window_tree_host_->IsActive() &&
          wm::IsActiveWindow(content_window_);
 }
 
@@ -940,28 +946,28 @@
 }
 
 ui::ZOrderLevel DesktopNativeWidgetAura::GetZOrderLevel() const {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     return desktop_window_tree_host_->GetZOrderLevel();
   return ui::ZOrderLevel::kNormal;
 }
 
 void DesktopNativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetVisibleOnAllWorkspaces(always_visible);
 }
 
 bool DesktopNativeWidgetAura::IsVisibleOnAllWorkspaces() const {
-  return content_window_ &&
+  return desktop_window_tree_host_ &&
          desktop_window_tree_host_->IsVisibleOnAllWorkspaces();
 }
 
 void DesktopNativeWidgetAura::Maximize() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->Maximize();
 }
 
 void DesktopNativeWidgetAura::Minimize() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->Minimize();
   internal::RootView* root_view =
       static_cast<internal::RootView*>(GetWidget()->GetRootView());
@@ -969,15 +975,15 @@
 }
 
 bool DesktopNativeWidgetAura::IsMaximized() const {
-  return content_window_ && desktop_window_tree_host_->IsMaximized();
+  return desktop_window_tree_host_ && desktop_window_tree_host_->IsMaximized();
 }
 
 bool DesktopNativeWidgetAura::IsMinimized() const {
-  return content_window_ && desktop_window_tree_host_->IsMinimized();
+  return desktop_window_tree_host_ && desktop_window_tree_host_->IsMinimized();
 }
 
 void DesktopNativeWidgetAura::Restore() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->Restore();
 }
 
@@ -985,7 +991,7 @@
                                             int64_t target_display_id) {
   // The `target_display_id` argument is unsupported in Aura.
   DCHECK_EQ(target_display_id, display::kInvalidDisplayId);
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetFullscreen(fullscreen);
 }
 
@@ -997,17 +1003,17 @@
     bool can_appear_in_existing_fullscreen_spaces) {}
 
 void DesktopNativeWidgetAura::SetOpacity(float opacity) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetOpacity(opacity);
 }
 
 void DesktopNativeWidgetAura::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetAspectRatio(aspect_ratio);
 }
 
 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->FlashFrame(flash_frame);
 }
 
@@ -1081,20 +1087,20 @@
     const gfx::Vector2d& drag_offset,
     Widget::MoveLoopSource source,
     Widget::MoveLoopEscapeBehavior escape_behavior) {
-  if (!content_window_)
+  if (!desktop_window_tree_host_)
     return Widget::MoveLoopResult::kCanceled;
   return desktop_window_tree_host_->RunMoveLoop(drag_offset, source,
                                                 escape_behavior);
 }
 
 void DesktopNativeWidgetAura::EndMoveLoop() {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->EndMoveLoop();
 }
 
 void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled(
     bool value) {
-  if (content_window_)
+  if (desktop_window_tree_host_)
     desktop_window_tree_host_->SetVisibilityChangedAnimationsEnabled(value);
 }
 
@@ -1124,7 +1130,7 @@
 }
 
 bool DesktopNativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
-  return content_window_ &&
+  return desktop_window_tree_host_ &&
          desktop_window_tree_host_->IsTranslucentWindowOpacitySupported();
 }
 
diff --git a/ui/webui/resources/cr_components/history_clusters/clusters.ts b/ui/webui/resources/cr_components/history_clusters/clusters.ts
index 3504abe..089a1a4 100644
--- a/ui/webui/resources/cr_components/history_clusters/clusters.ts
+++ b/ui/webui/resources/cr_components/history_clusters/clusters.ts
@@ -183,12 +183,12 @@
   }
 
   private onRemoveButtonClick_() {
-    this.pageHandler_.removeVisits(this.visitsToBeRemoved_)
-        .then(({accepted}) => {
-          if (!accepted) {
-            this.visitsToBeRemoved_ = [];
-          }
-        });
+    this.pageHandler_.removeVisits(this.visitsToBeRemoved_).then(() => {
+      // The returned promise resolves with whether the request succeeded in the
+      // browser. That value may be used to show a toast but is ignored for now.
+      // Allow remove requests again.
+      this.visitsToBeRemoved_ = [];
+    });
     this.$.confirmationDialog.get().close();
   }
 
@@ -336,15 +336,15 @@
   }
 
   /**
-   * Called when the last accepted request to browser to remove visits succeeds.
+   * Called with the original remove params when the last accepted request to
+   * browser to remove visits succeeds.
    */
-  private onVisitsRemoved_() {
+  private onVisitsRemoved_(removedVisits: Array<URLVisit>) {
     // Show the confirmation toast once done removing one visit only; since a
     // confirmation dialog was not shown prior to the action.
-    if (this.visitsToBeRemoved_.length === 1) {
+    if (removedVisits.length === 1) {
       this.$.confirmationToast.get().show();
     }
-    this.visitsToBeRemoved_ = [];
   }
 }
 
diff --git a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
index 0280618..9d6949aa 100644
--- a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
+++ b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
@@ -177,8 +177,8 @@
   // Requests to remove all visits to the specified URLs in the specified
   // timespan in `visits`. This includes the less recent visits to the same set
   // of URLs whose information is preserved in `visits`. The returned Promise
-  // indicates if the request was accepted by the browser.
-  RemoveVisits(array<URLVisit> visits) => (bool accepted);
+  // resolves with whether the request succeeded in the History backend layer.
+  RemoveVisits(array<URLVisit> visits) => (bool success);
 
   // Requests to open the URLs in `visits` in a new tab group.
   OpenVisitUrlsInTabGroup(array<URLVisit> visits);