Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2298)

Unified Diff: content/browser/tab_contents/render_view_host_manager.cc

Issue 6319001: Support window.opener after a process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update comments. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/tab_contents/render_view_host_manager.cc
diff --git a/content/browser/tab_contents/render_view_host_manager.cc b/content/browser/tab_contents/render_view_host_manager.cc
index 973a1d0e7832c4490cc74e698f2fce67dfc8d133..d06ccf53afe70d572d8491ef56e234636ac5621c 100644
--- a/content/browser/tab_contents/render_view_host_manager.cc
+++ b/content/browser/tab_contents/render_view_host_manager.cc
@@ -49,6 +49,13 @@ RenderViewHostManager::~RenderViewHostManager() {
RenderViewHost* render_view_host = render_view_host_;
render_view_host_ = NULL;
render_view_host->Shutdown();
+
+ // Shut down any swapped out RenderViewHosts.
+ for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
+ iter != swapped_out_hosts_.end();
+ ++iter) {
+ iter->second->Shutdown();
+ }
}
void RenderViewHostManager::Init(Profile* profile,
@@ -148,21 +155,17 @@ bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
if (pending_render_view_host_->are_navigations_suspended())
pending_render_view_host_->SetNavigationsSuspended(false);
} else {
- // The request has been started and paused, while we're waiting for the
+ // The request has been started and paused while we're waiting for the
// unload handler to finish. We'll pretend that it did, by notifying the
// IO thread to let the response continue. The pending renderer will then
// be swapped in as part of the usual DidNavigate logic. (If the unload
// handler later finishes, this call will be ignored because the state in
// CrossSiteResourceHandler will already be cleaned up.)
- ViewMsg_ClosePage_Params params;
- params.closing_process_id =
- render_view_host_->process()->id();
- params.closing_route_id = render_view_host_->routing_id();
- params.for_cross_site_transition = true;
+ ViewMsg_SwapOut_Params params;
params.new_render_process_host_id =
pending_render_view_host_->process()->id();
params.new_request_id = pending_request_id;
- current_host()->process()->CrossSiteClosePageACK(params);
+ current_host()->process()->CrossSiteSwapOutACK(params);
}
return false;
}
@@ -244,7 +247,7 @@ void RenderViewHostManager::ShouldClosePage(bool for_cross_site_transition,
if (proceed_to_fire_unload) {
// This is not a cross-site navigation, the tab is being closed.
- render_view_host_->ClosePage(false, -1, -1);
+ render_view_host_->ClosePage();
}
}
}
@@ -256,12 +259,12 @@ void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id,
return;
DCHECK(pending_render_view_host_);
- // Tell the old renderer to run its onunload handler. When it finishes, it
- // will send a ClosePage_ACK to the ResourceDispatcherHost with the given
- // IDs (of the pending RVH's request), allowing the pending RVH's response to
- // resume.
- render_view_host_->ClosePage(true,
- new_render_process_host_id, new_request_id);
+ // Tell the old renderer it is being swapped out. This will fire the unload
+ // handler (without firing the beforeunload handler a second time). When the
+ // unload handler finishes and the navigation completes, we will send a
+ // message to the ResourceDispatcherHost with the given pending request IDs,
+ // allowing the pending RVH's response to resume.
+ render_view_host_->SwapOut(new_render_process_host_id, new_request_id);
// ResourceDispatcherHost has told us to run the onunload handler, which
// means it is not a download or unsafe page, and we are going to perform the
@@ -459,6 +462,17 @@ bool RenderViewHostManager::CreatePendingRenderView(
// we're about to switch away, so that it sends an UpdateState message.
}
+ // Check if we've already created an RVH for this SiteInstance.
+ CHECK(instance);
+ RenderViewHostMap::iterator iter =
+ swapped_out_hosts_.find(instance->id());
+ if (iter != swapped_out_hosts_.end()) {
+ // Re-use the existing RenderViewHost, which has already been initialized.
+ // We'll remove it from the list of swapped out hosts if it commits.
+ pending_render_view_host_ = iter->second;
+ return true;
+ }
+
pending_render_view_host_ = RenderViewHostFactory::Create(
instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_->
GetControllerForRenderManager().session_storage_namespace());
@@ -515,9 +529,7 @@ void RenderViewHostManager::CommitPending() {
bool focus_render_view = !will_focus_location_bar &&
render_view_host_->view() && render_view_host_->view()->HasFocus();
- // Hide the current view and prepare to destroy it.
- // TODO(creis): Get the old RenderViewHost to send us an UpdateState message
- // before we destroy it.
+ // Hide the current view and prepare to swap it out.
if (render_view_host_->view())
render_view_host_->view()->Hide();
RenderViewHost* old_render_view_host = render_view_host_;
@@ -526,6 +538,13 @@ void RenderViewHostManager::CommitPending() {
render_view_host_ = pending_render_view_host_;
pending_render_view_host_ = NULL;
+ // If the pending view was on the swapped out list, we can remove it.
+ RenderViewHostMap::iterator iter = swapped_out_hosts_.find(
+ render_view_host_->site_instance()->id());
+ if (iter != swapped_out_hosts_.end()) {
+ swapped_out_hosts_.erase(iter);
+ }
+
// If the view is gone, then this RenderViewHost died while it was hidden.
// We ignored the RenderViewGone call at the time, so we should send it now
// to make sure the sad tab shows up, etc.
@@ -550,7 +569,9 @@ void RenderViewHostManager::CommitPending() {
Source<NavigationController>(&delegate_->GetControllerForRenderManager()),
Details<RenderViewHostSwitchedDetails>(&details));
- old_render_view_host->Shutdown();
+ // Keep track of the old swapped out RVH in case we navigate back to it.
+ swapped_out_hosts_[old_render_view_host->site_instance()->id()] =
+ old_render_view_host;
// Let the task manager know that we've swapped RenderViewHosts, since it
// might need to update its process groupings.
@@ -661,7 +682,11 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate(
void RenderViewHostManager::CancelPending() {
RenderViewHost* pending_render_view_host = pending_render_view_host_;
pending_render_view_host_ = NULL;
- pending_render_view_host->Shutdown();
+
+ // Only shutdown the pending RVH if it isn't currently swapped out.
+ // This can happen if we abort a pending load.
+ if (!IsSwappedOut(pending_render_view_host))
+ pending_render_view_host->Shutdown();
pending_web_ui_.reset();
}
@@ -681,9 +706,10 @@ void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) {
}
void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) {
+ // TODO(creis): Abstract out the common code between this and CommitPending.
web_ui_.reset();
- // Hide the current view and prepare to destroy it.
+ // Hide the current view and prepare to swap it out.
if (render_view_host_->view())
render_view_host_->view()->Hide();
RenderViewHost* old_render_view_host = render_view_host_;
@@ -704,6 +730,13 @@ void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) {
render_view_host_->view()->Show();
}
+ // If the given RVH was on the swapped out list, we can remove it.
+ RenderViewHostMap::iterator iter = swapped_out_hosts_.find(
+ render_view_host_->site_instance()->id());
+ if (iter != swapped_out_hosts_.end()) {
+ swapped_out_hosts_.erase(iter);
+ }
+
delegate_->UpdateRenderViewSizeForRenderManager();
RenderViewHostSwitchedDetails details;
@@ -714,10 +747,19 @@ void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) {
Source<NavigationController>(&delegate_->GetControllerForRenderManager()),
Details<RenderViewHostSwitchedDetails>(&details));
- // This will cause the old RenderViewHost to delete itself.
- old_render_view_host->Shutdown();
+ // Keep track of the old swapped out RVH in case we navigate back to it.
+ swapped_out_hosts_[old_render_view_host->site_instance()->id()] =
+ old_render_view_host;
// Let the task manager know that we've swapped RenderViewHosts, since it
// might need to update its process groupings.
delegate_->NotifySwappedFromRenderManager();
}
+
+bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
+ if (!rvh->site_instance())
+ return false;
+
+ return swapped_out_hosts_.find(rvh->site_instance()->id()) !=
+ swapped_out_hosts_.end();
+}

Powered by Google App Engine
This is Rietveld 408576698