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()));
}
}