Commit 8f6a95d8 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Chromium LUCI CQ

Prerender: Avoid starting navigation for prerendering when it is duplicate

This CL avoids starting navigation for prerendering when it already
started for the same URL.

To do that, this moves PrerenderHost::StartNavigation() call into
PrerenderHostRegistry::RegisterHost(). This doesn't change behavior
around networking. Even before this change, the duplicate navigation
didn't issue a network request because PrerenderHost was destroyed right
after PrerenderHost::StartNavigation() was called. The browser tests
make sure this behavior.

In addition to that, this change renames RegisterHost() to
CreateAndStartHost() and then moves the PrerenderHost creation into the
function for code cleanup.

Bug: 1132746
Change-Id: Ibc1d51921d845c2746a1a0caca27e08e77256699
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2567514Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833583}
parent 71ad7332
......@@ -18,16 +18,29 @@ PrerenderHostRegistry::PrerenderHostRegistry() {
PrerenderHostRegistry::~PrerenderHostRegistry() = default;
void PrerenderHostRegistry::RegisterHost(
const GURL& prerendering_url,
std::unique_ptr<PrerenderHost> prerender_host) {
void PrerenderHostRegistry::CreateAndStartHost(
blink::mojom::PrerenderAttributesPtr attributes,
const GlobalFrameRoutingId& initiator_render_frame_host_id,
const url::Origin& initiator_origin) {
DCHECK(attributes);
// Ignore prerendering requests for the same URL.
if (base::Contains(prerender_host_by_url_, prerendering_url)) {
// TODO(https://crbug.com/1132746): In addition to this check, we may have
// to avoid duplicate requests in the PrerenderHost layer so that the
// prerender host doesn't start navigation for the duplicate requests.
const GURL prerendering_url = attributes->url;
if (base::Contains(prerender_host_by_url_, prerendering_url))
return;
}
auto prerender_host = std::make_unique<PrerenderHost>(
std::move(attributes), initiator_render_frame_host_id, initiator_origin);
// Start prerendering before adding the host to the map to make sure
// navigation for prerendering doesn't select itself.
// TODO(https://crbug.com/1132746): SelectForNavigation() should avoid select
// a prerender host when the current NavigationRequest is for prerendering
// regardless of the calling order of StartPrerendering(). This modification
// would require the proper `is_prerendering` state in NavigationRequest,
// RenderFrameHostImpl, or somewhere else.
prerender_host->StartPrerendering();
prerender_host_by_url_[prerendering_url] = std::move(prerender_host);
}
......
......@@ -8,7 +8,10 @@
#include <map>
#include "content/common/content_export.h"
#include "content/public/browser/global_routing_id.h"
#include "third_party/blink/public/mojom/prerender/prerender.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
......@@ -19,7 +22,7 @@ class PrerenderHost;
// to navigation code for activating prerendered contents. This is created and
// owned by StoragePartitionImpl.
//
// TODO(https://crbug.com/1132746): Once the Prerender2 is migrated to the
// TODO(https://crbug.com/1154501): Once the Prerender2 is migrated to the
// MPArch, it would be more natural to make PrerenderHostRegistry scoped to
// WebContents, that is, WebContents will own this.
class CONTENT_EXPORT PrerenderHostRegistry {
......@@ -32,9 +35,11 @@ class CONTENT_EXPORT PrerenderHostRegistry {
PrerenderHostRegistry(PrerenderHostRegistry&&) = delete;
PrerenderHostRegistry& operator=(PrerenderHostRegistry&&) = delete;
// Registers the host for `prerendering_url`.
void RegisterHost(const GURL& prerendering_url,
std::unique_ptr<PrerenderHost> prerender_host);
// Creates and starts a host for `prerendering_url`.
void CreateAndStartHost(
blink::mojom::PrerenderAttributesPtr attributes,
const GlobalFrameRoutingId& initiator_render_frame_host_id,
const url::Origin& initiator_origin);
// Destroys the host registered for `prerendering_url`.
void AbandonHost(const GURL& prerendering_url);
......
......@@ -49,17 +49,10 @@ void PrerenderProcessor::Start(
prerendering_url_ = attributes->url;
// Start prerendering.
auto prerender_host = std::make_unique<PrerenderHost>(
GetPrerenderHostRegistry().CreateAndStartHost(
std::move(attributes),
initiator_render_frame_host_.GetGlobalFrameRoutingId(),
initiator_origin_);
prerender_host->StartPrerendering();
// Register the prerender host to PrerenderHostRegistry so that navigation can
// find this prerendered contents.
GetPrerenderHostRegistry().RegisterHost(prerendering_url_,
std::move(prerender_host));
}
void PrerenderProcessor::Cancel() {
......
......@@ -24,8 +24,8 @@ class RenderFrameHostImpl;
// request (see comments on the mojom interface for details) and owned by the
// initiator RenderFrameHostImpl's mojo::UniqueReceiverSet.
//
// When Start() is called from a renderer process, this instantiates a new
// PrerenderHost, and forwards the request to the prerender host.
// When Start() is called from a renderer process, this asks
// PrerenderHostRegistry to create a PrerenderHost and start prerendering.
class CONTENT_EXPORT PrerenderProcessor final
: public blink::mojom::PrerenderProcessor {
public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment