Index: content/browser/web_contents/web_contents_impl.cc |
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc |
index 6d04a4152cb2bd7430e5751bae2089564dba2572..727ea2a5ff819fbce6d9f3f0628986907409c202 100644 |
--- a/content/browser/web_contents/web_contents_impl.cc |
+++ b/content/browser/web_contents/web_contents_impl.cc |
@@ -1738,10 +1738,16 @@ bool WebContentsImpl::NavigateToEntry( |
return false; |
} |
- // TODO(creis): Use entry->frame_tree_node_id() to pick which |
- // RenderFrameHostManager to use. |
+ // Use entry->frame_tree_node_id() to pick which RenderFrameHostManager to |
+ // use. |
+ int64 frame_tree_node_id = frame_tree_.root()->frame_tree_node_id(); |
+ if (entry.frame_tree_node_id() != -1) |
+ frame_tree_node_id = entry.frame_tree_node_id(); |
+ |
+ RenderFrameHostManager* manager = |
+ frame_tree_.FindByID(frame_tree_node_id)->render_manager(); |
RenderViewHostImpl* dest_render_view_host = |
- static_cast<RenderViewHostImpl*>(GetRenderManager()->Navigate(entry)); |
+ static_cast<RenderViewHostImpl*>(manager->Navigate(entry)); |
if (!dest_render_view_host) |
return false; // Unable to create the desired render view host. |
@@ -1768,6 +1774,9 @@ bool WebContentsImpl::NavigateToEntry( |
current_load_start_ = base::TimeTicks::Now(); |
// Navigate in the desired RenderViewHost. |
+ // TODO(creis): As a temporary hack, we currently do cross-process subframe |
+ // navigations in a top-level frame of the new process. Thus, we don't yet |
+ // need to store the correct frame ID in ViewMsg_Navigate_Params. |
ViewMsg_Navigate_Params navigate_params; |
MakeNavigateParams(entry, controller_, delegate_, reload_type, |
&navigate_params); |
@@ -2968,11 +2977,38 @@ void WebContentsImpl::DidGetRedirectForResourceRequest( |
void WebContentsImpl::DidNavigate( |
RenderViewHost* rvh, |
- const ViewHostMsg_FrameNavigate_Params& params) { |
- if (frame_tree_.IsFirstNavigationAfterSwap()) { |
+ const ViewHostMsg_FrameNavigate_Params& orig_params) { |
+ ViewHostMsg_FrameNavigate_Params params(orig_params); |
+ RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(rvh); |
+ if (!rvhi->HasFrameID(params.frame_id)) { |
// First navigation should be a main frame navigation. |
- DCHECK(PageTransitionIsMainFrame(params.transition)); |
- frame_tree_.OnFirstNavigationAfterSwap(params.frame_id); |
+ // TODO(creis): This DCHECK is disabled for now because cross-process |
+ // subframe navigations currently have a main frame PageTransition. |
+ //DCHECK(PageTransitionIsMainFrame(params.transition)); |
+ rvhi->RegisterFrameID(params.frame_id, |
+ frame_tree_.root()->frame_tree_node_id()); |
+ } |
+ |
+ // Look up the FrameTreeNode ID that the renderer-specific frame ID |
+ // corresponds to. |
+ int frame_tree_node_id = rvhi->GetFrameTreeNodeID(params.frame_id); |
+ |
+ // TODO(creis): In the short term, cross-process subframe navigations are |
+ // happening in the pending RenderViewHost's top-level frame. (We need to |
+ // both mirror the frame tree and get the navigation to occur in the correct |
+ // subframe to fix this.) Until then, we should check whether we have a |
+ // pending NavigationEntry with a frame ID and if so, treat the cross-process |
+ // "main frame" navigation as a subframe navigation. This limits us to a |
+ // single cross-process subframe per RVH, and it affects NavigateToEntry and |
+ // DidStartProvisionalLoad. |
+ NavigationEntryImpl* pending_entry = NavigationEntryImpl::FromNavigationEntry( |
+ controller_.GetPendingEntry()); |
+ int root_ftn_id = frame_tree_.root()->frame_tree_node_id(); |
+ if (pending_entry && |
+ pending_entry->frame_tree_node_id() != -1 && |
+ pending_entry->frame_tree_node_id() != root_ftn_id) { |
+ params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
+ frame_tree_node_id = pending_entry->frame_tree_node_id(); |
} |
if (PageTransitionIsMainFrame(params.transition)) { |
@@ -2984,9 +3020,16 @@ void WebContentsImpl::DidNavigate( |
// that may have just been swapped out. |
if (delegate_ && delegate_->CanOverscrollContent()) |
controller_.TakeScreenshot(); |
+ } |
- GetRenderManager()->DidNavigateMainFrame(rvh); |
+ FrameTreeNode* frame = frame_tree_.FindByID(frame_tree_node_id); |
+ if (!frame) { |
+ // Just for debugging. We can't trust the renderer to lie about the ID. |
+ NOTREACHED(); |
+ return; |
} |
+ // TODO(creis): Rename to DidNavigateFrame. |
+ frame->render_manager()->DidNavigateMainFrame(rvh); |
// Update the site of the SiteInstance if it doesn't have one yet, unless |
// assigning a site is not necessary for this URL. In that case, the |
@@ -3009,12 +3052,12 @@ void WebContentsImpl::DidNavigate( |
contents_mime_type_ = params.contents_mime_type; |
LoadCommittedDetails details; |
- bool did_navigate = controller_.RendererDidNavigate(params, &details); |
+ bool did_navigate = controller_.RendererDidNavigate(rvh, params, &details); |
// For now, keep track of each frame's URL in its FrameTreeNode. This lets |
// us estimate our process count for implementing OOP iframes. |
// TODO(creis): Remove this when we track which pages commit in each frame. |
- frame_tree_.SetFrameUrl(params.frame_id, params.url); |
+ frame_tree_.SetFrameUrl(frame_tree_node_id, params.url); |
// Send notification about committed provisional loads. This notification is |
// different from the NAV_ENTRY_COMMITTED notification which doesn't include |
@@ -3284,8 +3327,11 @@ void WebContentsImpl::RequestTransferURL( |
GetSiteInstance(), url)) |
dest_url = GURL(kAboutBlankURL); |
- // TODO(creis): Look up the FrameTreeNode ID corresponding to source_frame_id. |
- int frame_tree_node_id = -1; |
+ int64 frame_tree_node_id = -1; |
+ if (source_frame_id != -1) { |
+ frame_tree_node_id = static_cast<RenderViewHostImpl*>( |
+ GetRenderViewHost())->GetFrameTreeNodeID(source_frame_id); |
+ } |
OpenURLParams params(dest_url, referrer, source_frame_id, |
frame_tree_node_id, disposition, |
page_transition, true /* is_renderer_initiated */); |