Index: content/browser/frame_host/render_frame_host_manager.cc |
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc |
index b5e1d4885562508e36d629412c352f8bd1815012..e6ead664201ce380b2c194a7b354d2aa7a9e04c6 100644 |
--- a/content/browser/frame_host/render_frame_host_manager.cc |
+++ b/content/browser/frame_host/render_frame_host_manager.cc |
@@ -107,7 +107,8 @@ void RenderFrameHostManager::Init(BrowserContext* browser_context, |
// TODO(creis): Make render_frame_host_ a scoped_ptr. |
render_frame_host_ = CreateRenderFrameHost(site_instance, view_routing_id, |
- frame_routing_id, false, false); |
+ frame_routing_id, false, |
+ delegate_->IsHidden()); |
// Keep track of renderer processes as they start to shut down or are |
// crashed/killed. |
@@ -193,6 +194,7 @@ RenderViewHostImpl* RenderFrameHostManager::Navigate( |
} else { |
// This is our primary renderer, notify here as we won't be calling |
// CommitPending (which does the notify). |
+ // TODO(creis): only do this for top-level frames, when the RVH changes. |
delegate_->NotifySwappedFromRenderManager( |
NULL, render_frame_host_->render_view_host()); |
} |
@@ -254,7 +256,7 @@ bool RenderFrameHostManager::ShouldCloseTabOnUnresponsiveRenderer() { |
return false; |
} |
-// TODO(creis): This should take in a RenderFrameHost. |
+// TODO(creis): Remove this in favor of SwappedOutFrame. |
void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
// Make sure this is from our current RVH, and that we have a pending |
// navigation from OnCrossSiteResponse. (There may be no pending navigation |
@@ -266,6 +268,10 @@ void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
return; |
} |
+ // We should probably sanity check that this is for the correct frame. |
+ // TODO(creis): Is this frame ID trusted? Which frame is it for? |
+ //DCHECK_EQ(frame_tree_node_->GetID()?, pending_nav_params_->frame_id); |
+ |
// Now that the unload handler has run, we need to either initiate the |
// pending transfer (if there is one) or resume the paused response (if not). |
// TODO(creis): The blank swapped out page is visible during this time, but |
@@ -281,6 +287,7 @@ void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
// We don't know whether the original request had |user_action| set to true. |
// However, since we force the navigation to be in the current tab, it |
// doesn't matter. |
+ // TODO(creis): Move RequestTransferURL to RenderFrameHost's navigator. |
render_view_host->GetDelegate()->RequestTransferURL( |
transfer_url, |
pending_nav_params_->transfer_url_chain, |
@@ -301,6 +308,57 @@ void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
pending_nav_params_.reset(); |
} |
+void RenderFrameHostManager::SwappedOutFrame( |
+ RenderFrameHostImpl* render_frame_host) { |
+ // Make sure this is from our current RFH, and that we have a pending |
+ // navigation from OnCrossSiteResponse. (There may be no pending navigation |
+ // for data URLs that don't make network requests, for example.) If not, |
+ // just return early and ignore. |
+ if (render_frame_host != render_frame_host_ || !pending_nav_params_.get()) { |
+ pending_nav_params_.reset(); |
+ return; |
+ } |
+ |
+ // We should probably sanity check that this is for the correct frame. |
+ // TODO(creis): Is this frame ID trusted? Which frame is it for? |
+ //DCHECK_EQ(frame_tree_node_->GetID()?, pending_nav_params_->frame_id); |
+ |
+ // Now that the unload handler has run, we need to either initiate the |
+ // pending transfer (if there is one) or resume the paused response (if not). |
+ // TODO(creis): The blank swapped out page is visible during this time, but |
+ // we can shorten this by delivering the response directly, rather than |
+ // forcing an identical request to be made. |
+ if (pending_nav_params_->is_transfer) { |
+ // Treat the last URL in the chain as the destination and the remainder as |
+ // the redirect chain. |
+ CHECK(pending_nav_params_->transfer_url_chain.size()); |
+ GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); |
+ pending_nav_params_->transfer_url_chain.pop_back(); |
+ |
+ // We don't know whether the original request had |user_action| set to true. |
+ // However, since we force the navigation to be in the current tab, it |
+ // doesn't matter. |
+ // TODO(creis): Move RequestTransferURL to RenderFrameHost's navigator. |
+ render_frame_host->render_view_host()->GetDelegate()->RequestTransferURL( |
+ transfer_url, |
+ pending_nav_params_->transfer_url_chain, |
+ pending_nav_params_->referrer, |
+ pending_nav_params_->page_transition, |
+ CURRENT_TAB, |
+ pending_nav_params_->frame_id, |
+ pending_nav_params_->global_request_id, |
+ false, |
+ true); |
+ } else if (pending_render_frame_host_) { |
+ RenderProcessHostImpl* pending_process = |
+ static_cast<RenderProcessHostImpl*>( |
+ pending_render_frame_host_->GetProcess()); |
+ pending_process->ResumeDeferredNavigation( |
+ pending_nav_params_->global_request_id); |
+ } |
+ pending_nav_params_.reset(); |
+} |
+ |
// TODO(creis): This should take in a RenderFrameHost. |
void RenderFrameHostManager::DidNavigateMainFrame( |
RenderViewHost* render_view_host) { |
@@ -480,13 +538,16 @@ void RenderFrameHostManager::SwapOutOldPage() { |
// unload handler finishes and the navigation completes, we will send a |
// message to the ResourceDispatcherHost, allowing the pending RVH's response |
// to resume. |
- // TODO(creis): We should do this on the RFH or else we'll swap out the |
- // top-level page when subframes navigate. |
- render_frame_host_->render_view_host()->SwapOut(); |
+ // Note: this must be done on the RFH or else we'll swap out the |
+ // top-level page. |
+ if (frame_tree_node_->IsMainFrame()) |
+ render_frame_host_->render_view_host()->SwapOut(); |
+ else |
+ render_frame_host_->SwapOut(); |
// 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 |
- // navigation. Thus, we no longer need to remember that the RenderViewHost |
+ // navigation. Thus, we no longer need to remember that the RenderFrameHost |
// is part of a pending cross-site request. |
if (pending_render_frame_host_) { |
pending_render_frame_host_->render_view_host()-> |
@@ -776,6 +837,12 @@ RenderFrameHostImpl* RenderFrameHostManager::CreateRenderFrameHost( |
site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); |
} else { |
render_view_host = frame_tree->GetRenderViewHostForSubFrame(site_instance); |
+ // TODO(creis): Mirror the frame tree so this check isn't necessary. |
+ if (!render_view_host) { |
+ render_view_host = frame_tree->CreateRenderViewHostForMainFrame( |
+ site_instance, view_routing_id, frame_routing_id, swapped_out, |
+ hidden); |
+ } |
} |
// TODO(creis): Make render_frame_host a scoped_ptr. |
@@ -832,7 +899,8 @@ int RenderFrameHostManager::CreateRenderFrame( |
if (success && frame_tree_node_->IsMainFrame()) { |
// Don't show the main frame's view until we get a DidNavigate from it. |
render_view_host->GetView()->Hide(); |
- } else if (!swapped_out) { |
+ } else if (!swapped_out && pending_render_frame_host_) { |
+ // TODO(creis): The lack of pending RFH check from before was a bug. |
CancelPending(); |
} |
} |
@@ -908,20 +976,21 @@ void RenderFrameHostManager::CommitPending() { |
render_frame_host_->render_view_host()->GetView() && |
render_frame_host_->render_view_host()->GetView()->HasFocus(); |
+ // TODO(creis): As long as show/hide are on RVH, we don't want to do them for |
+ // subframe navigations or they'll interfere with the top-level page. |
+ bool is_main_frame = frame_tree_node_->IsMainFrame(); |
+ |
// Swap in the pending frame and make it active. Also ensure the FrameTree |
// stays in sync. |
RenderFrameHostImpl* old_render_frame_host = render_frame_host_; |
render_frame_host_ = pending_render_frame_host_; |
pending_render_frame_host_ = NULL; |
- render_frame_host_->render_view_host()->AttachToFrameTree(); |
+ if (is_main_frame) |
+ frame_tree_node_->frame_tree()->ResetForMainFrameSwap(); |
// The process will no longer try to exit, so we can decrement the count. |
render_frame_host_->GetProcess()->RemovePendingView(); |
- // TODO(creis): As long as show/hide are on RVH, we don't want to do them for |
- // subframe navigations or they'll interfere with the top-level page. |
- bool is_main_frame = frame_tree_node_->IsMainFrame(); |
- |
// If the view is gone, then this RenderViewHost died while it was hidden. |
// We ignored the RenderProcessGone call at the time, so we should send it now |
// to make sure the sad tab shows up, etc. |
@@ -933,9 +1002,17 @@ void RenderFrameHostManager::CommitPending() { |
} |
// Hide the old view now that the new one is visible. |
+ // TODO(creis): We don't want to hide the top-level view based on a frame |
+ // swap. Hack for now. |
if (old_render_frame_host->render_view_host()->GetView()) { |
- old_render_frame_host->render_view_host()->GetView()->Hide(); |
- old_render_frame_host->render_view_host()->WasSwappedOut(); |
+ if (is_main_frame) { |
+ old_render_frame_host->render_view_host()->GetView()->Hide(); |
+ old_render_frame_host->render_view_host()->WasSwappedOut(); |
+ } else { |
+ // TODO(creis): We'll need to set this back to false when navigating a |
+ // subframe RFH, but we can't navigate a subframe RFH yet. |
+ old_render_frame_host->set_swapped_out(true); |
+ } |
} |
// Make sure the size is up to date. (Fix for bug 1079768.) |
@@ -966,7 +1043,8 @@ void RenderFrameHostManager::CommitPending() { |
if (old_render_frame_host->render_view_host()->IsRenderViewLive()) { |
// If the old RFH is live, we are swapping it out and should keep track of |
// it in case we navigate back to it. |
- DCHECK(old_render_frame_host->render_view_host()->is_swapped_out()); |
+ DCHECK(old_render_frame_host->is_swapped_out() || |
+ old_render_frame_host->render_view_host()->is_swapped_out()); |
// Temp fix for http://crbug.com/90867 until we do a better cleanup to make |
// sure we don't get different rvh instances for the same site instance |
// in the same rvhmgr. |