| Index: content/browser/web_contents/render_view_host_manager.cc
|
| diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc
|
| index c167333623d82f11f32401fb98e9ff652ba7646f..31cb7ed2d3231aef1d82b1e5ffc50fc94f3f8052 100644
|
| --- a/content/browser/web_contents/render_view_host_manager.cc
|
| +++ b/content/browser/web_contents/render_view_host_manager.cc
|
| @@ -75,7 +75,7 @@ void RenderViewHostManager::Init(content::BrowserContext* browser_context,
|
| site_instance = SiteInstance::Create(browser_context);
|
| render_view_host_ = static_cast<RenderViewHostImpl*>(
|
| RenderViewHostFactory::Create(
|
| - site_instance, render_view_delegate_, routing_id, delegate_->
|
| + site_instance, render_view_delegate_, routing_id, false, delegate_->
|
| GetControllerForRenderManager().GetSessionStorageNamespace()));
|
|
|
| // Keep track of renderer processes as they start to shut down.
|
| @@ -112,13 +112,14 @@ RenderViewHostImpl* RenderViewHostManager::Navigate(
|
| !render_view_host_->IsRenderViewLive()) {
|
| // Note: we don't call InitRenderView here because we are navigating away
|
| // soon anyway, and we don't have the NavigationEntry for this host.
|
| - delegate_->CreateRenderViewForRenderManager(render_view_host_);
|
| + delegate_->CreateRenderViewForRenderManager(render_view_host_,
|
| + MSG_ROUTING_NONE);
|
| }
|
|
|
| // If the renderer crashed, then try to create a new one to satisfy this
|
| // navigation request.
|
| if (!dest_render_view_host->IsRenderViewLive()) {
|
| - if (!InitRenderView(dest_render_view_host, entry))
|
| + if (!InitRenderView(dest_render_view_host, MSG_ROUTING_NONE))
|
| return NULL;
|
|
|
| // Now that we've created a new renderer, be sure to hide it if it isn't
|
| @@ -543,62 +544,64 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
|
| // BrowsingInstance. It is important to immediately give this new
|
| // SiteInstance to a RenderViewHost (if it is different than our current
|
| // SiteInstance), so that it is ref counted. This will happen in
|
| - // CreatePendingRenderView.
|
| + // CreateRenderView.
|
| return curr_instance->GetRelatedSiteInstance(dest_url);
|
| }
|
| }
|
|
|
| -bool RenderViewHostManager::CreatePendingRenderView(
|
| - const NavigationEntryImpl& entry, SiteInstance* instance) {
|
| - NavigationEntry* curr_entry =
|
| - delegate_->GetControllerForRenderManager().GetLastCommittedEntry();
|
| - if (curr_entry) {
|
| - DCHECK(!curr_entry->GetContentState().empty());
|
| - // TODO(creis): Should send a message to the RenderView to let it know
|
| - // we're about to switch away, so that it sends an UpdateState message.
|
| - }
|
| -
|
| - // Check if we've already created an RVH for this SiteInstance.
|
| +int RenderViewHostManager::CreateRenderView(
|
| + SiteInstance* instance,
|
| + int opener_route_id,
|
| + bool swapped_out) {
|
| CHECK(instance);
|
| - RenderViewHostMap::iterator iter =
|
| - swapped_out_hosts_.find(instance->GetId());
|
| - 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;
|
|
|
| + // Check if we've already created an RVH for this SiteInstance. If so, try
|
| + // to re-use the existing one, which has already been initialized. We'll
|
| + // remove it from the list of swapped out hosts if it commits.
|
| + RenderViewHostImpl* new_render_view_host = static_cast<RenderViewHostImpl*>(
|
| + GetSwappedOutRenderViewHost(instance));
|
| + if (new_render_view_host) {
|
| // Prevent the process from exiting while we're trying to use it.
|
| - pending_render_view_host_->GetProcess()->AddPendingView();
|
| -
|
| - return true;
|
| - }
|
| + new_render_view_host->GetProcess()->AddPendingView();
|
| + } else {
|
| + // Create a new RenderViewHost if we don't find an existing one.
|
| + new_render_view_host = static_cast<RenderViewHostImpl*>(
|
| + RenderViewHostFactory::Create(instance,
|
| + render_view_delegate_, MSG_ROUTING_NONE, swapped_out, delegate_->
|
| + GetControllerForRenderManager().GetSessionStorageNamespace()));
|
|
|
| - pending_render_view_host_ = static_cast<RenderViewHostImpl*>(
|
| - RenderViewHostFactory::Create(
|
| - instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_->
|
| - GetControllerForRenderManager().GetSessionStorageNamespace()));
|
| + // Prevent the process from exiting while we're trying to use it.
|
| + new_render_view_host->GetProcess()->AddPendingView();
|
|
|
| - // Prevent the process from exiting while we're trying to use it.
|
| - pending_render_view_host_->GetProcess()->AddPendingView();
|
| + // Store the new RVH as swapped out if necessary.
|
| + if (swapped_out)
|
| + swapped_out_hosts_[instance->GetId()] = new_render_view_host;
|
|
|
| - bool success = InitRenderView(pending_render_view_host_, entry);
|
| - if (success) {
|
| - // Don't show the view until we get a DidNavigate from it.
|
| - pending_render_view_host_->GetView()->Hide();
|
| - } else {
|
| - CancelPending();
|
| + bool success = InitRenderView(new_render_view_host, opener_route_id);
|
| + if (success) {
|
| + // Don't show the view until we get a DidNavigate from it.
|
| + new_render_view_host->GetView()->Hide();
|
| + } else if (!swapped_out) {
|
| + CancelPending();
|
| + }
|
| }
|
| - return success;
|
| +
|
| + // Use this as our new pending RVH if it isn't swapped out.
|
| + if (!swapped_out)
|
| + pending_render_view_host_ = new_render_view_host;
|
| +
|
| + return new_render_view_host->GetRoutingID();
|
| }
|
|
|
| bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
|
| - const NavigationEntryImpl& entry) {
|
| + int opener_route_id) {
|
| // If the pending navigation is to a WebUI, tell the RenderView about any
|
| // bindings it will need enabled.
|
| if (pending_web_ui())
|
| render_view_host->AllowBindings(pending_web_ui()->GetBindings());
|
|
|
| - return delegate_->CreateRenderViewForRenderManager(render_view_host);
|
| + return delegate_->CreateRenderViewForRenderManager(render_view_host,
|
| + opener_route_id);
|
| }
|
|
|
| void RenderViewHostManager::CommitPending() {
|
| @@ -737,9 +740,19 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
|
| delegate_->CreateWebUIForRenderManager(entry.GetURL()));
|
| pending_and_current_web_ui_.reset();
|
|
|
| - // Create a pending RVH and navigate it.
|
| - bool success = CreatePendingRenderView(entry, new_instance);
|
| - if (!success)
|
| + // Ensure that we have created RVHs for the new RVH's opener chain if
|
| + // we are staying in the same BrowsingInstance. This allows the pending RVH
|
| + // to send cross-process script calls to its opener(s).
|
| + int opener_route_id = MSG_ROUTING_NONE;
|
| + if (new_instance->IsRelatedSiteInstance(curr_instance)) {
|
| + opener_route_id =
|
| + delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
|
| + }
|
| +
|
| + // Create a non-swapped-out pending RVH with the given opener and navigate
|
| + // it.
|
| + int route_id = CreateRenderView(new_instance, opener_route_id, false);
|
| + if (route_id == MSG_ROUTING_NONE)
|
| return NULL;
|
|
|
| // Check if our current RVH is live before we set up a transition.
|
| @@ -878,3 +891,12 @@ bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
|
| return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) !=
|
| swapped_out_hosts_.end();
|
| }
|
| +
|
| +RenderViewHost* RenderViewHostManager::GetSwappedOutRenderViewHost(
|
| + SiteInstance* instance) {
|
| + RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
|
| + if (iter != swapped_out_hosts_.end())
|
| + return iter->second;
|
| +
|
| + return NULL;
|
| +}
|
|
|