| 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..06ab825123e4b1fd294dd577e6aee18ab9ff94fe 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_ = CreateWebUI(url, bindings);
|
| pending_and_current_web_ui_.reset();
|
| +}
|
| +
|
| +scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
|
| + int bindings) {
|
| + scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
|
|
|
| // 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"));
|
| + return nullptr;
|
| }
|
| + return new_web_ui.Pass();
|
| }
|
|
|
| RenderFrameHostImpl* RenderFrameHostManager::Navigate(
|
| @@ -557,6 +559,30 @@ void RenderFrameHostManager::SwapOutOldFrame(
|
| }
|
| }
|
|
|
| +void RenderFrameHostManager::DiscardUnusedFrame(
|
| + 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.
|
| + 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);
|
| + 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
|
| @@ -990,16 +1016,32 @@ const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance(
|
| return current_instance->GetSiteURL();
|
| }
|
|
|
| -void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance(
|
| +void RenderFrameHostManager::CreatePendingRenderFrameHost(
|
| SiteInstance* old_instance,
|
| SiteInstance* new_instance,
|
| bool is_main_frame) {
|
| 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_ =
|
| + CreateRenderFrame(new_instance, pending_web_ui(), opener_route_id,
|
| + create_render_frame_flags, 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,
|
| + WebUIImpl* web_ui,
|
| + int opener_route_id,
|
| + int flags,
|
| + int* view_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 (view_routing_id_ptr)
|
| + *view_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 (view_routing_id_ptr)
|
| + *view_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 (view_routing_id_ptr)
|
| + *view_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) {
|
| @@ -1439,8 +1477,8 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
|
| // otherwise CancelPending may clear the pending_web_ui_ and the page will
|
| // not have its bindings set appropriately.
|
| SetPendingWebUI(url, bindings);
|
| - CreateRenderFrameHostForNewSiteInstance(
|
| - current_instance, new_instance.get(), frame_tree_node_->IsMainFrame());
|
| + CreatePendingRenderFrameHost(current_instance, new_instance.get(),
|
| + frame_tree_node_->IsMainFrame());
|
| if (!pending_render_frame_host_.get()) {
|
| return NULL;
|
| }
|
| @@ -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();
|
| - }
|
| + DiscardUnusedFrame(pending_render_frame_host.Pass());
|
|
|
| pending_web_ui_.reset();
|
| pending_and_current_web_ui_.reset();
|
|
|