Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 1 | // Copyright 2022 The Chromium Authors |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 5 | #include "content/browser/preloading/prerenderer_impl.h" |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 6 | |
Arthur Sonzogni | d5ce01f7 | 2024-12-13 13:35:28 | [diff] [blame] | 7 | #include <array> |
| 8 | |
Lei Zhang | 0a85e65a | 2025-05-23 19:22:06 | [diff] [blame] | 9 | #include "base/strings/string_number_conversions.h" |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 10 | #include "base/test/scoped_feature_list.h" |
Kevin McNee | 842eb0a | 2024-04-11 20:14:16 | [diff] [blame] | 11 | #include "content/browser/preloading/preloading_confidence.h" |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 12 | #include "content/browser/preloading/prerender/prerender_features.h" |
Lei Zhang | 5686e52 | 2023-03-02 17:33:10 | [diff] [blame] | 13 | #include "content/browser/preloading/prerender/prerender_host_registry.h" |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 14 | #include "content/public/browser/web_contents_delegate.h" |
| 15 | #include "content/public/common/content_client.h" |
Johann | a4bf1cd | 2022-11-30 23:59:39 | [diff] [blame] | 16 | #include "content/public/test/prerender_test_util.h" |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 17 | #include "content/public/test/test_browser_context.h" |
| 18 | #include "content/public/test/test_renderer_host.h" |
| 19 | #include "content/test/test_content_browser_client.h" |
| 20 | #include "content/test/test_web_contents.h" |
| 21 | #include "testing/gtest/include/gtest/gtest.h" |
| 22 | |
| 23 | namespace content { |
| 24 | namespace { |
| 25 | |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 26 | class PrerendererTest : public RenderViewHostTestHarness { |
| 27 | public: |
Johann | a4bf1cd | 2022-11-30 23:59:39 | [diff] [blame] | 28 | PrerendererTest() = default; |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 29 | |
| 30 | void SetUp() override { |
| 31 | RenderViewHostTestHarness::SetUp(); |
| 32 | |
| 33 | browser_context_ = std::make_unique<TestBrowserContext>(); |
| 34 | web_contents_ = TestWebContents::Create( |
| 35 | browser_context_.get(), |
| 36 | SiteInstanceImpl::Create(browser_context_.get())); |
Johann | becce08 | 2023-01-17 05:14:32 | [diff] [blame] | 37 | web_contents_delegate_ = |
| 38 | std::make_unique<test::ScopedPrerenderWebContentsDelegate>( |
| 39 | *web_contents_); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 40 | web_contents_->NavigateAndCommit(GURL("https://example.com")); |
| 41 | } |
| 42 | |
| 43 | void TearDown() override { |
| 44 | web_contents_.reset(); |
| 45 | browser_context_.reset(); |
| 46 | RenderViewHostTestHarness::TearDown(); |
| 47 | } |
| 48 | |
| 49 | RenderFrameHostImpl* GetRenderFrameHost() { |
| 50 | return web_contents_->GetPrimaryMainFrame(); |
| 51 | } |
| 52 | |
| 53 | GURL GetSameOriginUrl(const std::string& path) { |
| 54 | return GURL("https://example.com" + path); |
| 55 | } |
| 56 | |
| 57 | GURL GetCrossSiteUrl(const std::string& path) { |
| 58 | return GURL("https://example2.com" + path); |
| 59 | } |
| 60 | |
| 61 | PrerenderHostRegistry* GetPrerenderHostRegistry() const { |
| 62 | return web_contents_->GetPrerenderHostRegistry(); |
| 63 | } |
| 64 | |
| 65 | blink::mojom::SpeculationCandidatePtr CreatePrerenderCandidate( |
| 66 | const GURL& url) { |
| 67 | auto candidate = blink::mojom::SpeculationCandidate::New(); |
| 68 | candidate->action = blink::mojom::SpeculationAction::kPrerender; |
| 69 | candidate->url = url; |
| 70 | candidate->referrer = blink::mojom::Referrer::New(); |
Takashi Nakayama | 978f0a15 | 2025-06-17 08:26:25 | [diff] [blame] | 71 | candidate->eagerness = blink::mojom::SpeculationEagerness::kImmediate; |
Hiroki Nakagawa | c91e3622 | 2025-05-02 11:00:27 | [diff] [blame] | 72 | candidate->tags = {std::nullopt}; |
Taiyo Mizuhashi | f277ece | 2024-01-12 17:29:28 | [diff] [blame] | 73 | return candidate; |
| 74 | } |
| 75 | |
| 76 | blink::mojom::SpeculationCandidatePtr CreatePrerenderCandidateWithEagerness( |
| 77 | const GURL& url, |
| 78 | blink::mojom::SpeculationEagerness eagerness) { |
| 79 | blink::mojom::SpeculationCandidatePtr candidate = |
| 80 | CreatePrerenderCandidate(url); |
| 81 | candidate->eagerness = eagerness; |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 82 | return candidate; |
| 83 | } |
| 84 | |
| 85 | private: |
Johann | a4bf1cd | 2022-11-30 23:59:39 | [diff] [blame] | 86 | test::ScopedPrerenderFeatureList prerender_feature_list_; |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 87 | std::unique_ptr<TestBrowserContext> browser_context_; |
| 88 | std::unique_ptr<TestWebContents> web_contents_; |
Johann | becce08 | 2023-01-17 05:14:32 | [diff] [blame] | 89 | std::unique_ptr<test::ScopedPrerenderWebContentsDelegate> |
| 90 | web_contents_delegate_; |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 91 | }; |
| 92 | |
| 93 | // Tests that Prerenderer starts prerendering when it receives prerender |
| 94 | // speculation candidates. |
| 95 | TEST_F(PrerendererTest, StartPrerender) { |
| 96 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 97 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 98 | |
| 99 | const GURL kPrerenderingUrl = GetSameOriginUrl("/empty.html"); |
| 100 | std::vector<blink::mojom::SpeculationCandidatePtr> candidates; |
| 101 | candidates.push_back(CreatePrerenderCandidate(kPrerenderingUrl)); |
| 102 | |
Adithya Srinivasan | 94ec2fea | 2023-05-01 17:02:15 | [diff] [blame] | 103 | prerenderer.ProcessCandidatesForPrerender(std::move(candidates)); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 104 | EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl)); |
| 105 | } |
| 106 | |
Yoichi Osato | fed56ff8 | 2024-02-29 01:13:45 | [diff] [blame] | 107 | // Tests that Prerenderer should not start prerendering when |
| 108 | // kLCPTimingPredictorPrerender2 is enabled and until OnLCPPredicted is called. |
| 109 | TEST_F(PrerendererTest, LCPTimingPredictorPrerender2) { |
| 110 | base::test::ScopedFeatureList scoped_feature_list; |
| 111 | scoped_feature_list.InitAndEnableFeature( |
| 112 | blink::features::kLCPTimingPredictorPrerender2); |
| 113 | |
| 114 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
| 115 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
| 116 | |
| 117 | const GURL kPrerenderingUrl = GetSameOriginUrl("/empty.html"); |
| 118 | std::vector<blink::mojom::SpeculationCandidatePtr> candidates; |
| 119 | candidates.push_back(CreatePrerenderCandidate(kPrerenderingUrl)); |
| 120 | |
| 121 | prerenderer.ProcessCandidatesForPrerender(std::move(candidates)); |
| 122 | EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl)); |
| 123 | |
| 124 | prerenderer.OnLCPPredicted(); |
| 125 | EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl)); |
| 126 | } |
| 127 | |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 128 | // Tests that Prerenderer will skip a cross-site candidate even if it is the |
| 129 | // first prerender candidate in the candidate list. |
| 130 | TEST_F(PrerendererTest, ProcessFirstSameOriginPrerenderCandidate) { |
| 131 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 132 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 133 | |
| 134 | const GURL kFirstPrerenderingUrlCrossSite = GetCrossSiteUrl("/title.html"); |
| 135 | const GURL kSecondPrerenderingUrlSameOrigin = |
| 136 | GetSameOriginUrl("/title1.html"); |
| 137 | std::vector<blink::mojom::SpeculationCandidatePtr> candidates; |
| 138 | candidates.push_back( |
| 139 | CreatePrerenderCandidate(kFirstPrerenderingUrlCrossSite)); |
| 140 | candidates.push_back( |
| 141 | CreatePrerenderCandidate(kSecondPrerenderingUrlSameOrigin)); |
| 142 | |
Adithya Srinivasan | 94ec2fea | 2023-05-01 17:02:15 | [diff] [blame] | 143 | prerenderer.ProcessCandidatesForPrerender(std::move(candidates)); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 144 | |
| 145 | // The first prerender candidate is a cross-site one, so Prerenderer should |
| 146 | // not prerender it. |
| 147 | EXPECT_FALSE( |
| 148 | registry->FindHostByUrlForTesting(kFirstPrerenderingUrlCrossSite)); |
| 149 | // The second element in this list is the first same-origin prerender |
| 150 | // candidate, so Prerenderer should prerender this candidate. |
| 151 | EXPECT_TRUE( |
| 152 | registry->FindHostByUrlForTesting(kSecondPrerenderingUrlSameOrigin)); |
| 153 | } |
| 154 | |
Taiyo Mizuhashi | f277ece | 2024-01-12 17:29:28 | [diff] [blame] | 155 | class PrerenderHostRegistryObserver : public PrerenderHostRegistry::Observer { |
| 156 | public: |
| 157 | explicit PrerenderHostRegistryObserver( |
| 158 | PrerenderHostRegistry* prerender_host_registry) { |
| 159 | observation_.Observe(prerender_host_registry); |
| 160 | } |
| 161 | |
| 162 | void OnTrigger(const GURL& url) override { trigger_sequence_.push_back(url); } |
| 163 | |
| 164 | void OnRegistryDestroyed() override { observation_.Reset(); } |
| 165 | |
| 166 | const std::vector<GURL>& GetTriggerSequence() { return trigger_sequence_; } |
| 167 | |
| 168 | private: |
| 169 | base::ScopedObservation<PrerenderHostRegistry, |
| 170 | PrerenderHostRegistry::Observer> |
| 171 | observation_{this}; |
| 172 | |
| 173 | std::vector<GURL> trigger_sequence_; |
| 174 | }; |
| 175 | |
| 176 | // Test that ProcessCandidatesForPrerender will trigger candidates in the same |
| 177 | // order as the input of the candidate list (crbug.com/1505301). |
| 178 | TEST_F(PrerendererTest, TriggerPrerenderWithInsertionOrder) { |
| 179 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
| 180 | PrerenderHostRegistryObserver observer{registry}; |
| 181 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
| 182 | |
| 183 | std::vector<GURL> urls = { |
| 184 | GetSameOriginUrl("/empty.html?a"), |
| 185 | GetSameOriginUrl("/empty.html?c"), |
| 186 | GetSameOriginUrl("/empty.html?b"), |
| 187 | }; |
| 188 | |
| 189 | std::vector<blink::mojom::SpeculationCandidatePtr> candidates; |
| 190 | for (const auto& url : urls) { |
| 191 | candidates.push_back(CreatePrerenderCandidate(url)); |
| 192 | } |
| 193 | |
| 194 | prerenderer.ProcessCandidatesForPrerender(std::move(candidates)); |
| 195 | |
| 196 | for (const auto& url : urls) { |
| 197 | ASSERT_TRUE(registry->FindHostByUrlForTesting(url)); |
| 198 | } |
| 199 | EXPECT_EQ(observer.GetTriggerSequence(), urls); |
| 200 | } |
| 201 | |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 202 | // Tests that Prerenderer will remove the rendered host, if the url is removed |
| 203 | // from candidates list. |
| 204 | TEST_F(PrerendererTest, RemoveRendererHostAfterCandidateRemoved) { |
| 205 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 206 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 207 | |
Arthur Sonzogni | d5ce01f7 | 2024-12-13 13:35:28 | [diff] [blame] | 208 | const auto urls = std::to_array<GURL>( |
| 209 | {GetSameOriginUrl("/title1.html"), GetSameOriginUrl("/title2.html")}); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 210 | std::vector<blink::mojom::SpeculationCandidatePtr> candidates; |
| 211 | for (const auto& url : urls) { |
| 212 | candidates.push_back(CreatePrerenderCandidate(url)); |
| 213 | } |
Adithya Srinivasan | 94ec2fea | 2023-05-01 17:02:15 | [diff] [blame] | 214 | prerenderer.ProcessCandidatesForPrerender(std::move(candidates)); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 215 | EXPECT_TRUE(registry->FindHostByUrlForTesting(urls[0])); |
| 216 | EXPECT_TRUE(registry->FindHostByUrlForTesting(urls[1])); |
| 217 | |
| 218 | std::vector<blink::mojom::SpeculationCandidatePtr> new_candidates; |
| 219 | new_candidates.push_back(CreatePrerenderCandidate(urls[1])); |
Adithya Srinivasan | 94ec2fea | 2023-05-01 17:02:15 | [diff] [blame] | 220 | prerenderer.ProcessCandidatesForPrerender(std::move(new_candidates)); |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 221 | EXPECT_FALSE(registry->FindHostByUrlForTesting(urls[0])); |
| 222 | EXPECT_TRUE(registry->FindHostByUrlForTesting(urls[1])); |
| 223 | |
| 224 | prerenderer.ProcessCandidatesForPrerender( |
| 225 | std::vector<blink::mojom::SpeculationCandidatePtr>{}); |
| 226 | EXPECT_FALSE(registry->FindHostByUrlForTesting(urls[0])); |
| 227 | EXPECT_FALSE(registry->FindHostByUrlForTesting(urls[1])); |
| 228 | } |
| 229 | |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 230 | // Tests that Prerenderer will remove the host if the host is canceled with |
Takashi Nakayama | 978f0a15 | 2025-06-17 08:26:25 | [diff] [blame] | 231 | // non-immediate limit, and the canceled host can be reprocessed. |
| 232 | TEST_F(PrerendererTest, RemoveRendererHostAfterNonImmediateLimitCancel) { |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 233 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
| 234 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
| 235 | |
| 236 | std::vector<GURL> urls; |
| 237 | |
| 238 | // Prerender as many times as limit + 1. All prerenders should be started |
| 239 | // once. |
Domenic Denicola | 959e57a | 2025-06-11 09:16:09 | [diff] [blame] | 240 | for (int i = 0; |
Takashi Nakayama | 978f0a15 | 2025-06-17 08:26:25 | [diff] [blame] | 241 | i < PrerenderHostRegistry:: |
| 242 | kMaxRunningSpeculationRulesNonImmediatePrerenders + |
| 243 | 1; |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 244 | i++) { |
| 245 | const GURL url = GetSameOriginUrl("/empty.html?" + base::ToString(i)); |
| 246 | urls.push_back(url); |
| 247 | blink::mojom::SpeculationCandidatePtr candidate = |
| 248 | CreatePrerenderCandidateWithEagerness( |
| 249 | url, blink::mojom::SpeculationEagerness::kConservative); |
Kevin McNee | 98e068a | 2024-04-09 20:12:34 | [diff] [blame] | 250 | prerenderer.MaybePrerender(std::move(candidate), |
Kevin McNee | 842eb0a | 2024-04-11 20:14:16 | [diff] [blame] | 251 | preloading_predictor::kUnspecified, |
| 252 | PreloadingConfidence{100}); |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 253 | |
| 254 | EXPECT_TRUE(registry->FindHostByUrlForTesting(url)); |
| 255 | } |
| 256 | |
Domenic Denicola | 959e57a | 2025-06-11 09:16:09 | [diff] [blame] | 257 | for (int i = 0; |
Takashi Nakayama | 978f0a15 | 2025-06-17 08:26:25 | [diff] [blame] | 258 | i < PrerenderHostRegistry:: |
| 259 | kMaxRunningSpeculationRulesNonImmediatePrerenders + |
| 260 | 1; |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 261 | i++) { |
| 262 | if (i == 0) { |
| 263 | // The first (= oldest) prerender should be removed since the (limit + |
| 264 | // 1)-th prerender was started. |
| 265 | EXPECT_FALSE(registry->FindHostByUrlForTesting(urls[i])); |
| 266 | } else { |
| 267 | EXPECT_TRUE(registry->FindHostByUrlForTesting(urls[i])); |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | // Retrigger canceled host. It should be started and instead the second oldest |
| 272 | // prerender should be canceled. |
| 273 | blink::mojom::SpeculationCandidatePtr candidate = |
| 274 | CreatePrerenderCandidateWithEagerness( |
| 275 | urls[0], blink::mojom::SpeculationEagerness::kConservative); |
Kevin McNee | 98e068a | 2024-04-09 20:12:34 | [diff] [blame] | 276 | prerenderer.MaybePrerender(std::move(candidate), |
Kevin McNee | 842eb0a | 2024-04-11 20:14:16 | [diff] [blame] | 277 | preloading_predictor::kUnspecified, |
| 278 | PreloadingConfidence{100}); |
Domenic Denicola | 959e57a | 2025-06-11 09:16:09 | [diff] [blame] | 279 | for (int i = 0; |
Takashi Nakayama | 978f0a15 | 2025-06-17 08:26:25 | [diff] [blame] | 280 | i < PrerenderHostRegistry:: |
| 281 | kMaxRunningSpeculationRulesNonImmediatePrerenders + |
| 282 | 1; |
Taiyo Mizuhashi | f8dcaed | 2023-10-05 18:38:55 | [diff] [blame] | 283 | i++) { |
| 284 | if (i == 1) { |
| 285 | EXPECT_FALSE(registry->FindHostByUrlForTesting(urls[i])); |
| 286 | } else { |
| 287 | EXPECT_TRUE(registry->FindHostByUrlForTesting(urls[i])); |
| 288 | } |
| 289 | } |
| 290 | } |
| 291 | |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 292 | // Tests that it is possible to start a prerender using MaybePrerender and |
| 293 | // ShouldWaitForPrerenderResult methods. |
| 294 | TEST_F(PrerendererTest, MaybePrerenderAndShouldWaitForPrerenderResult) { |
| 295 | PrerenderHostRegistry* registry = GetPrerenderHostRegistry(); |
| 296 | PrerendererImpl prerenderer(*GetRenderFrameHost()); |
| 297 | |
| 298 | const GURL kUrlToCancel = GetSameOriginUrl("/to_cancel.html"); |
| 299 | std::vector<blink::mojom::SpeculationCandidatePtr> candidateToCancel; |
| 300 | candidateToCancel.push_back(CreatePrerenderCandidate(kUrlToCancel)); |
| 301 | |
| 302 | // Candidate is not processed yet. So, it should return false. |
| 303 | EXPECT_FALSE(prerenderer.ShouldWaitForPrerenderResult(kUrlToCancel)); |
| 304 | // Process the candidate. |
Adithya Srinivasan | 94ec2fea | 2023-05-01 17:02:15 | [diff] [blame] | 305 | prerenderer.ProcessCandidatesForPrerender(std::move(candidateToCancel)); |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 306 | EXPECT_TRUE(prerenderer.ShouldWaitForPrerenderResult(kUrlToCancel)); |
| 307 | // Cancel the prerender |
| 308 | prerenderer.ProcessCandidatesForPrerender( |
| 309 | std::vector<blink::mojom::SpeculationCandidatePtr>{}); |
| 310 | EXPECT_FALSE(prerenderer.ShouldWaitForPrerenderResult(kUrlToCancel)); |
| 311 | |
| 312 | const GURL kPrerenderingUrl = GetSameOriginUrl("/empty.html"); |
| 313 | const auto candidate = CreatePrerenderCandidate(kPrerenderingUrl); |
| 314 | |
| 315 | // Candidate is not processed yet. So, it should return false. |
| 316 | EXPECT_FALSE(prerenderer.ShouldWaitForPrerenderResult(kPrerenderingUrl)); |
| 317 | // MaybePrerender the candidate and check if ShouldWaitForPrerenderResult |
| 318 | // returns true. |
Kevin McNee | 98e068a | 2024-04-09 20:12:34 | [diff] [blame] | 319 | EXPECT_TRUE(prerenderer.MaybePrerender(candidate, |
Kevin McNee | 842eb0a | 2024-04-11 20:14:16 | [diff] [blame] | 320 | preloading_predictor::kUnspecified, |
| 321 | PreloadingConfidence{100})); |
Iman Saboori | 31bed87 | 2022-12-09 15:41:31 | [diff] [blame] | 322 | EXPECT_TRUE(prerenderer.ShouldWaitForPrerenderResult(kPrerenderingUrl)); |
| 323 | EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl)); |
| 324 | } |
| 325 | |
Iman Saboori | 03a661d | 2022-11-17 04:37:59 | [diff] [blame] | 326 | } // namespace |
| 327 | } // namespace content |