Prerender: Add NavigationThrottle for prerendering navigation
This CL adds NavigationThrottle for prerendering navigation. This
cancels prerendering when it navigates/redirects the main frame to
cross-origin.
For cross-origin navigation/redirection on iframes, that will be
deferred (not cancel prerendering) by a follow-up CL.
Bug: 1132746
Change-Id: If4e3b75222e88bb672f74144dcc6e844a78c0af9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2738780
Reviewed-by: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#861055}
diff --git a/content/browser/prerender/prerender_host_registry.cc b/content/browser/prerender/prerender_host_registry.cc
index 6100d576..2c6365d3 100644
--- a/content/browser/prerender/prerender_host_registry.cc
+++ b/content/browser/prerender/prerender_host_registry.cc
@@ -12,7 +12,6 @@
#include "base/system/sys_info.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/trace_conversion_helper.h"
-#include "content/browser/prerender/prerender_host.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "third_party/blink/public/common/features.h"
@@ -85,11 +84,22 @@
void PrerenderHostRegistry::AbandonHost(int frame_tree_node_id) {
TRACE_EVENT1("navigation", "PrerenderHostRegistry::AbandonHost",
"frame_tree_node_id", frame_tree_node_id);
- auto found = prerender_host_by_frame_tree_node_id_.find(frame_tree_node_id);
- if (found != prerender_host_by_frame_tree_node_id_.end()) {
- auto initial_url = found->second->GetInitialUrl();
- frame_tree_node_id_by_url_.erase(initial_url);
- prerender_host_by_frame_tree_node_id_.erase(found);
+ AbandonHostInternal(frame_tree_node_id);
+}
+
+void PrerenderHostRegistry::AbandonHostAsync(
+ int frame_tree_node_id,
+ PrerenderHost::FinalStatus final_status) {
+ TRACE_EVENT1("navigation", "PrerenderHostRegistry::AbandonHostAsync",
+ "frame_tree_node_id", frame_tree_node_id);
+ // Remove the prerender host from the host maps so that it's not used for
+ // activation during asynchronous deletion.
+ std::unique_ptr<PrerenderHost> prerender_host =
+ AbandonHostInternal(frame_tree_node_id);
+ prerender_host->RecordFinalStatus(PassKey(), final_status);
+ if (prerender_host) {
+ // Asynchronously delete the prerender host.
+ GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, std::move(prerender_host));
}
}
@@ -178,6 +188,13 @@
reserved_prerender_host_by_frame_tree_node_id_.erase(frame_tree_node_id);
}
+PrerenderHost* PrerenderHostRegistry::FindHostById(int frame_tree_node_id) {
+ auto id_iter = prerender_host_by_frame_tree_node_id_.find(frame_tree_node_id);
+ if (id_iter == prerender_host_by_frame_tree_node_id_.end())
+ return nullptr;
+ return id_iter->second.get();
+}
+
PrerenderHost* PrerenderHostRegistry::FindHostByUrlForTesting(
const GURL& prerendering_url) {
auto id_iter = frame_tree_node_id_by_url_.find(prerendering_url);
@@ -190,6 +207,17 @@
return host_iter->second.get();
}
+std::unique_ptr<PrerenderHost> PrerenderHostRegistry::AbandonHostInternal(
+ int frame_tree_node_id) {
+ auto found = prerender_host_by_frame_tree_node_id_.find(frame_tree_node_id);
+ if (found == prerender_host_by_frame_tree_node_id_.end())
+ return nullptr;
+ std::unique_ptr<PrerenderHost> prerender_host = std::move(found->second);
+ frame_tree_node_id_by_url_.erase(prerender_host->GetInitialUrl());
+ prerender_host_by_frame_tree_node_id_.erase(found);
+ return prerender_host;
+}
+
void PrerenderHostRegistry::NotifyTrigger(const GURL& url) {
for (Observer& obs : observers_)
obs.OnTrigger(url);