Chromium Code Reviews| 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 7780cc05e2c90df1464137488038106a0f2316f6..c60f5484f7b1d9caa12c4e0cde19a42825280e4c 100644 | 
| --- a/content/browser/frame_host/render_frame_host_manager.cc | 
| +++ b/content/browser/frame_host/render_frame_host_manager.cc | 
| @@ -134,23 +134,25 @@ RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() { | 
| return iter->second; | 
| } | 
| -void RenderFrameHostManager::SetPendingWebUI(const GURL& url, | 
| - int bindings) { | 
| - pending_web_ui_.reset( | 
| - delegate_->CreateWebUIForRenderManager(url)); | 
| +void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) { | 
| + pending_web_ui_.reset(CreateWebUI(url, bindings)); | 
| pending_and_current_web_ui_.reset(); | 
| +} | 
| + | 
| +WebUIImpl* RenderFrameHostManager::CreateWebUI(const GURL& url, int bindings) { | 
| + WebUIImpl* new_web_ui = delegate_->CreateWebUIForRenderManager(url); | 
| 
 
Charlie Reis
2014/11/26 00:42:54
If this were a scoped_ptr, we wouldn't need the de
 
carlosk
2014/11/27 11:02:43
Understood and as it involved changing only one ex
 
 | 
| // If we have assigned (zero or more) bindings to this NavigationEntry in the | 
| // past, make sure we're not granting it different bindings than it had | 
| // before. If so, note it and don't give it any bindings, to avoid a | 
| // potential privilege escalation. | 
| - if (pending_web_ui_.get() && | 
| - bindings != NavigationEntryImpl::kInvalidBindings && | 
| - pending_web_ui_->GetBindings() != bindings) { | 
| - RecordAction( | 
| - base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | 
| - pending_web_ui_.reset(); | 
| + if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings && | 
| + new_web_ui->GetBindings() != bindings) { | 
| + RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | 
| + delete new_web_ui; | 
| + return nullptr; | 
| } | 
| + return new_web_ui; | 
| } | 
| RenderFrameHostImpl* RenderFrameHostManager::Navigate( | 
| @@ -557,6 +559,30 @@ void RenderFrameHostManager::SwapOutOldFrame( | 
| } | 
| } | 
| +void RenderFrameHostManager::DiscardRenderFrameHost( | 
| + scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 
| + // TODO(carlosk): this code is very similar to what can be found in | 
| + // SwapOutOldFrame and we should see that these are unified at some point. | 
| + | 
| + // If the SiteInstance for the pending RFH is being used by others, don't | 
| + // delete the RFH, just swap it out and it can be reused at a later point. | 
| 
 
Charlie Reis
2014/11/26 01:06:40
nit: This is a run-on sentence, so use a semicolon
 
carlosk
2014/11/27 11:02:43
Done.
 
 | 
| + SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); | 
| + if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { | 
| + // Any currently suspended navigations are no longer needed. | 
| + render_frame_host->CancelSuspendedNavigations(); | 
| + | 
| + RenderFrameProxyHost* proxy = | 
| + new RenderFrameProxyHost(site_instance, frame_tree_node_); | 
| + proxy_hosts_[site_instance->GetId()] = proxy; | 
| + render_frame_host->SwapOut(proxy); | 
| 
 
Charlie Reis
2014/11/26 01:06:40
This makes sense when called by CancelPending.
Ar
 
carlosk
2014/11/27 11:02:43
Yes, it should be a topic for the other CL.
But a
 
Charlie Reis
2014/12/01 20:12:46
Sounds good.
 
 | 
| + if (frame_tree_node_->IsMainFrame()) | 
| + proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | 
| + } else { | 
| + // We won't be coming back, so delete this one. | 
| + render_frame_host.reset(); | 
| + } | 
| +} | 
| + | 
| void RenderFrameHostManager::MoveToPendingDeleteHosts( | 
| scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 
| // |render_frame_host| will be deleted when its SwapOut ACK is received, or | 
| @@ -997,9 +1023,25 @@ void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( | 
| int create_render_frame_flags = 0; | 
| if (is_main_frame) | 
| create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; | 
| - // Ensure that we have created RFHs for the new RFH's opener chain if | 
| - // we are staying in the same BrowsingInstance. This allows the new RFH | 
| - // to send cross-process script calls to its opener(s). | 
| + | 
| + if (delegate_->IsHidden()) | 
| + create_render_frame_flags |= CREATE_RF_HIDDEN; | 
| + | 
| + int opener_route_id = | 
| + CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); | 
| + | 
| + if (pending_render_frame_host_) | 
| + CancelPending(); | 
| + | 
| + // Create a non-swapped-out RFH with the given opener. | 
| + pending_render_frame_host_ = | 
| 
 
Charlie Reis
2014/11/26 01:06:40
I see that it could be surprising that this method
 
carlosk
2014/11/27 11:02:44
Done: changed the name and updated the comment.
 
 | 
| + CreateRenderFrame(new_instance, opener_route_id, | 
| + create_render_frame_flags, pending_web_ui(), nullptr); | 
| +} | 
| + | 
| +int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded( | 
| + SiteInstance* old_instance, | 
| + SiteInstance* new_instance) { | 
| int opener_route_id = MSG_ROUTING_NONE; | 
| if (new_instance->IsRelatedSiteInstance(old_instance)) { | 
| opener_route_id = | 
| @@ -1012,17 +1054,7 @@ void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( | 
| frame_tree_node_, new_instance); | 
| } | 
| } | 
| - | 
| - if (delegate_->IsHidden()) | 
| - create_render_frame_flags |= CREATE_RF_HIDDEN; | 
| - | 
| - // Create a non-swapped-out RFH with the given opener. | 
| - int route_id = CreateRenderFrame(new_instance, opener_route_id, | 
| - create_render_frame_flags); | 
| - if (route_id == MSG_ROUTING_NONE) { | 
| - pending_render_frame_host_.reset(); | 
| - return; | 
| - } | 
| + return opener_route_id; | 
| } | 
| scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 
| @@ -1056,9 +1088,12 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 
| return render_frame_host.Pass(); | 
| } | 
| -int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| - int opener_route_id, | 
| - int flags) { | 
| +scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 
| + SiteInstance* instance, | 
| + int opener_route_id, | 
| + int flags, | 
| + const WebUIImpl* web_ui, | 
| + int* routing_id_ptr) { | 
| bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 
| CHECK(instance); | 
| // Swapped out views should always be hidden. | 
| @@ -1071,10 +1106,11 @@ int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| } | 
| scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | 
| - RenderFrameHostImpl* frame_to_announce = NULL; | 
| - int routing_id = MSG_ROUTING_NONE; | 
| + bool success = true; | 
| + if (routing_id_ptr) | 
| + *routing_id_ptr = MSG_ROUTING_NONE; | 
| - // We are creating a pending or swapped out RFH here. We should never create | 
| + // We are creating a pending or swapped out RFH here. We should never create | 
| // it in the same SiteInstance as our current RFH. | 
| CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 
| @@ -1082,9 +1118,9 @@ int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| // to re-use the existing one, which has already been initialized. We'll | 
| // remove it from the list of proxy hosts below if it will be active. | 
| RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 
| - | 
| if (proxy && proxy->render_frame_host()) { | 
| - routing_id = proxy->GetRenderViewHost()->GetRoutingID(); | 
| + if (routing_id_ptr) | 
| + *routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); | 
| // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 
| // Prevent the process from exiting while we're trying to use it. | 
| if (!swapped_out) { | 
| @@ -1098,13 +1134,13 @@ int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| // gets a RenderViewHost in the SiteInstance of its opener WebContents. | 
| // If not used in the first navigation, this RVH is swapped out and is not | 
| // granted bindings, so we may need to grant them when swapping it in. | 
| - if (pending_web_ui() && | 
| - !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | 
| - int required_bindings = pending_web_ui()->GetBindings(); | 
| - RenderViewHost* rvh = new_render_frame_host->render_view_host(); | 
| - if ((rvh->GetEnabledBindings() & required_bindings) != | 
| - required_bindings) { | 
| - rvh->AllowBindings(required_bindings); | 
| + if (web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | 
| + int required_bindings = web_ui->GetBindings(); | 
| + RenderViewHost* render_view_host = | 
| + new_render_frame_host->render_view_host(); | 
| + if ((render_view_host->GetEnabledBindings() & required_bindings) != | 
| + required_bindings) { | 
| + render_view_host->AllowBindings(required_bindings); | 
| } | 
| } | 
| } | 
| @@ -1129,7 +1165,7 @@ int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); | 
| } | 
| - bool success = | 
| + success = | 
| InitRenderView(render_view_host, opener_route_id, proxy_routing_id, | 
| !!(flags & CREATE_RF_FOR_MAIN_FRAME_NAVIGATION)); | 
| if (success) { | 
| @@ -1141,22 +1177,24 @@ int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 
| DCHECK(new_render_frame_host.get()); | 
| success = InitRenderFrame(new_render_frame_host.get()); | 
| } | 
| - } else if (!swapped_out && pending_render_frame_host_) { | 
| - CancelPending(); | 
| + if (success) { | 
| + if (routing_id_ptr) | 
| + *routing_id_ptr = render_view_host->GetRoutingID(); | 
| + // If a brand new RFH was created, announce it to observers. | 
| + if (new_render_frame_host) { | 
| + render_frame_delegate_->RenderFrameCreated( | 
| + new_render_frame_host.get()); | 
| + } | 
| + } | 
| } | 
| - routing_id = render_view_host->GetRoutingID(); | 
| - frame_to_announce = new_render_frame_host.get(); | 
| } | 
| - // Use this as our new pending RFH if it isn't swapped out. | 
| - if (!swapped_out) | 
| - pending_render_frame_host_ = new_render_frame_host.Pass(); | 
| - | 
| - // If a brand new RFH was created, announce it to observers. | 
| - if (frame_to_announce) | 
| - render_frame_delegate_->RenderFrameCreated(frame_to_announce); | 
| - | 
| - return routing_id; | 
| + // Returns the new RFH if it isn't swapped out. | 
| + if (success && !swapped_out) { | 
| + DCHECK(new_render_frame_host->GetSiteInstance() == instance); | 
| + return new_render_frame_host.Pass(); | 
| + } | 
| + return nullptr; | 
| } | 
| int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 
| @@ -1558,24 +1596,7 @@ void RenderFrameHostManager::CancelPending() { | 
| // We no longer need to prevent the process from exiting. | 
| pending_render_frame_host->GetProcess()->RemovePendingView(); | 
| - // If the SiteInstance for the pending RFH is being used by others, don't | 
| - // delete the RFH, just swap it out and it can be reused at a later point. | 
| - SiteInstanceImpl* site_instance = | 
| - pending_render_frame_host->GetSiteInstance(); | 
| - if (site_instance->active_frame_count() > 1) { | 
| - // Any currently suspended navigations are no longer needed. | 
| - pending_render_frame_host->CancelSuspendedNavigations(); | 
| - | 
| - RenderFrameProxyHost* proxy = | 
| - new RenderFrameProxyHost(site_instance, frame_tree_node_); | 
| - proxy_hosts_[site_instance->GetId()] = proxy; | 
| - pending_render_frame_host->SwapOut(proxy); | 
| - if (frame_tree_node_->IsMainFrame()) | 
| - proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); | 
| - } else { | 
| - // We won't be coming back, so delete this one. | 
| - pending_render_frame_host.reset(); | 
| - } | 
| + DiscardRenderFrameHost(pending_render_frame_host.Pass()); | 
| pending_web_ui_.reset(); | 
| pending_and_current_web_ui_.reset(); |