Hide previous NavigationEntry when doing an early RFH swap.

When the previous RFH has crashed and we eagerly swap in the
speculative RFH for a new navigation, ensure we do not show
the old URL above a potentially scriptable initial empty
document of the new RFH.

This approach can be removed after issue 1072817 is fixed.

Bug: 1111646, 1072817
Change-Id: I8ded08a40b6f3df17b072d66da31f728671e599f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2674708
Commit-Queue: Charlie Reis <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Cr-Commit-Position: refs/heads/master@{#852534}
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc
index f39c8f4..055f4bc 100644
--- a/content/browser/renderer_host/navigation_controller_impl.cc
+++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -3936,6 +3936,34 @@
   delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
 }
 
+void NavigationControllerImpl::HideEntryForEarlySwapAfterCrash(
+    RenderFrameHostImpl* rfh) {
+  // Nothing to do if there is no last committed entry to hide, or if we aren't
+  // swapping RenderFrameHosts before commit after a crash.
+  if (!GetLastCommittedEntry() || ShouldSkipEarlyCommitPendingForCrashedFrame())
+    return;
+
+  // Create a temporary about:blank NavigationEntry to show if we swap to a
+  // scriptable RenderFrameHost before the navigation commits (after a crash).
+  // The previous last committed entry will be set aside and restored if we go
+  // anywhere else or attempt a reload, just like a post-commit error page.
+  //
+  // Other uses of post-commit error pages will put the original entry back in
+  // RendererDidNavigate before creating a subsequent post-commit error page in
+  // InsertOrReplaceEntry.
+  //
+  // TODO(https://crbug.com/1072817): Remove this hack after we stop swapping
+  // RenderFrameHosts before the navigation commits.
+  InsertOrReplaceEntry(
+      std::make_unique<NavigationEntryImpl>(
+          rfh->GetSiteInstance(), GURL(url::kAboutBlankURL), Referrer(),
+          url::Origin() /* initiator origin */,
+          base::string16() /* extra_headers */, ui::PAGE_TRANSITION_LINK,
+          true /*is_renderer_initiated*/,
+          nullptr /* blob_url_loader_factory */),
+      true /* replace */, true /* was_post_commit_error */);
+}
+
 void NavigationControllerImpl::UpdateStateForFrame(
     RenderFrameHostImpl* rfhi,
     const blink::PageState& page_state) {