In WebContentsImpl, make it safe for WebContentsDelegate::AddNewContents
to delete the popup.

The Android implementation of WebContentsDelegate seems to do this sometimes,
so protect against it happening by means of a WeakPtr.

The main crash we've seen has been in ShowCreatedWindow(), but I've
spotted a much more low-volume equivalent that occurs in
CreateNewWindow() as well. This fixes both.

Revert the speculative fixes we previously landed for this bug.

BUG=680876

Review-Url: https://codereview.chromium.org/2675843002
Cr-Commit-Position: refs/heads/master@{#450121}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 260f219b..6fcb922d 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2116,8 +2116,6 @@
     // Save the created window associated with the route so we can show it
     // later.
     DCHECK_NE(MSG_ROUTING_NONE, main_frame_widget_route_id);
-    CHECK(RenderWidgetHostImpl::FromID(render_process_id,
-                                       main_frame_widget_route_id));
     pending_contents_[std::make_pair(
         render_process_id, main_frame_widget_route_id)] = new_contents;
     AddDestructionObserver(new_contents);
@@ -2135,9 +2133,15 @@
     bool was_blocked = false;
     if (delegate_) {
       gfx::Rect initial_rect;
+      base::WeakPtr<WebContentsImpl> weak_new_contents =
+          new_contents->weak_factory_.GetWeakPtr();
+
       delegate_->AddNewContents(
           this, new_contents, params.disposition, initial_rect,
           params.user_gesture, &was_blocked);
+
+      if (!weak_new_contents)
+        return;  // The delegate deleted |new_contents| during AddNewContents().
     }
     if (!was_blocked) {
       OpenURLParams open_params(params.target_url, params.referrer,
@@ -2215,27 +2219,25 @@
                                         WindowOpenDisposition disposition,
                                         const gfx::Rect& initial_rect,
                                         bool user_gesture) {
-  WebContentsImpl* contents =
+  WebContentsImpl* popup =
       GetCreatedWindow(process_id, main_frame_widget_route_id);
-  if (contents) {
-    RenderWidgetHostImpl* rwh =
-        RenderWidgetHostImpl::FromID(process_id, main_frame_widget_route_id);
-    if (!rwh) {
-      // TODO(nick): Temporary for https://crbug.com/680876
-      base::debug::DumpWithoutCrashing();
-      return;
-    }
-
+  if (popup) {
     WebContentsDelegate* delegate = GetDelegate();
-    contents->is_resume_pending_ = true;
+    popup->is_resume_pending_ = true;
     if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow())
-      contents->ResumeLoadingCreatedWebContents();
+      popup->ResumeLoadingCreatedWebContents();
 
     if (delegate) {
-      delegate->AddNewContents(this, contents, disposition, initial_rect,
-                               user_gesture, NULL);
+      base::WeakPtr<WebContentsImpl> weak_popup =
+          popup->weak_factory_.GetWeakPtr();
+      delegate->AddNewContents(this, popup, disposition, initial_rect,
+                               user_gesture, nullptr);
+      if (!weak_popup)
+        return;  // The delegate deleted |popup| during AddNewContents().
     }
 
+    RenderWidgetHostImpl* rwh = popup->GetMainFrame()->GetRenderWidgetHost();
+    DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
     rwh->Send(new ViewMsg_Move_ACK(rwh->GetRoutingID()));
   }
 }