11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/frame_host/render_frame_host_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/debug/trace_event.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/devtools/render_view_devtools_agent_host.h"
1481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch#include "content/browser/frame_host/debug_urls.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/interstitial_page_impl.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_controller_impl.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_factory.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/site_instance_impl.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/web_ui_controller_factory_registry.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/webui/web_ui_impl.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/port/browser/render_widget_host_view_port.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/render_widget_host_iterator.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_controller.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams()
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : is_transfer(false), frame_id(-1), should_replace_current_entry(false) {
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams(
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GlobalRequestID& global_request_id,
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool is_transfer,
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::vector<GURL>& transfer_url_chain,
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Referrer referrer,
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    PageTransition page_transition,
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int64 frame_id,
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool should_replace_current_entry)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : global_request_id(global_request_id),
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_transfer(is_transfer),
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      transfer_url_chain(transfer_url_chain),
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      referrer(referrer),
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      page_transition(page_transition),
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      frame_id(frame_id),
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      should_replace_current_entry(should_replace_current_entry) {
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderFrameHostManager::PendingNavigationParams::~PendingNavigationParams() {}
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderFrameHostManager::RenderFrameHostManager(
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderFrameHostDelegate* render_frame_delegate,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostDelegate* render_view_delegate,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostDelegate* render_widget_delegate,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Delegate* delegate)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cross_navigation_pending_(false),
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame_delegate_(render_frame_delegate),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_delegate_(render_view_delegate),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_widget_delegate_(render_widget_delegate),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host_(NULL),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_render_view_host_(NULL),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interstitial_page_(NULL) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderFrameHostManager::~RenderFrameHostManager() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_render_view_host_)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelPending();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should always have a main RenderViewHost except in some tests.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostImpl* render_view_host = render_view_host_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_ = NULL;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_view_host)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_host->Shutdown();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shut down any swapped out RenderViewHosts.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != swapped_out_hosts_.end();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second->Shutdown();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::Init(BrowserContext* browser_context,
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  SiteInstance* site_instance,
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int routing_id,
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int main_frame_routing_id) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a RenderViewHost, once we have an instance.  It is important to
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately give this SiteInstance to a RenderViewHost so that it is
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ref counted.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!site_instance)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    site_instance = SiteInstance::Create(browser_context);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_ = static_cast<RenderViewHostImpl*>(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderViewHostFactory::Create(
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          site_instance, render_view_delegate_, render_frame_delegate_,
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          render_widget_delegate_, routing_id, main_frame_routing_id, false,
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          delegate_->IsHidden()));
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  render_view_host_->AttachToFrameTree();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep track of renderer processes as they start to shut down or are
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // crashed/killed.
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 NotificationService::AllSources());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSING,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 NotificationService::AllSources());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderViewHostImpl* RenderFrameHostManager::current_host() const {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return render_view_host_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderViewHostImpl* RenderFrameHostManager::pending_render_view_host() const {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pending_render_view_host_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (interstitial_page_)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return interstitial_page_->GetView();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!render_view_host_)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return render_view_host_->GetView();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::SetPendingWebUI(const NavigationEntryImpl& entry) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_web_ui_.reset(
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_->CreateWebUIForRenderManager(entry.GetURL()));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_and_current_web_ui_.reset();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we have assigned (zero or more) bindings to this NavigationEntry in the
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // past, make sure we're not granting it different bindings than it had
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // before.  If so, note it and don't give it any bindings, to avoid a
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // potential privilege escalation.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pending_web_ui_.get() &&
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry.bindings() != NavigationEntryImpl::kInvalidBindings &&
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_web_ui_->GetBindings() != entry.bindings()) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordAction(UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pending_web_ui_.reset();
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderViewHostImpl* RenderFrameHostManager::Navigate(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NavigationEntryImpl& entry) {
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TRACE_EVENT0("browser", "RenderFrameHostManager:Navigate");
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a pending RenderViewHost. It will give us the one we should use
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostImpl* dest_render_view_host =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<RenderViewHostImpl*>(UpdateRendererStateForNavigate(entry));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dest_render_view_host)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;  // We weren't able to create a pending render view host.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the current render_view_host_ isn't live, we should create it so
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that we don't show a sad tab while the dest_render_view_host fetches
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its first page.  (Bug 1145340)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dest_render_view_host != render_view_host_ &&
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !render_view_host_->IsRenderViewLive()) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: we don't call InitRenderView here because we are navigating away
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // soon anyway, and we don't have the NavigationEntry for this host.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->CreateRenderViewForRenderManager(render_view_host_,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                MSG_ROUTING_NONE);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the renderer crashed, then try to create a new one to satisfy this
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation request.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dest_render_view_host->IsRenderViewLive()) {
173fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    // Recreate the opener chain.
174fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
175fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        dest_render_view_host->GetSiteInstance());
176fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    if (!InitRenderView(dest_render_view_host, opener_route_id))
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that we've created a new renderer, be sure to hide it if it isn't
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // our primary one.  Otherwise, we might crash if we try to call Show()
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on it later.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dest_render_view_host != render_view_host_ &&
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest_render_view_host->GetView()) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest_render_view_host->GetView()->Hide();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is our primary renderer, notify here as we won't be calling
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // CommitPending (which does the notify).
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      delegate_->NotifySwappedFromRenderManager(NULL, render_view_host_);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dest_render_view_host;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::Stop() {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_->Stop();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are cross-navigating, we should stop the pending renderers.  This
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will lead to a DidFailProvisionalLoad, which will properly destroy them.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cross_navigation_pending_) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host_->Send(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ViewMsg_Stop(pending_render_view_host_->GetRoutingID()));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::SetIsLoading(bool is_loading) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_->SetIsLoading(is_loading);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_render_view_host_)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host_->SetIsLoading(is_loading);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cross_navigation_pending_)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // We should always have a pending RVH when there's a cross-process navigation
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // in progress.  Sanity check this for http://crbug.com/276333.
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  CHECK(pending_render_view_host_);
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the tab becomes unresponsive during {before}unload while doing a
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cross-site navigation, proceed with the navigation.  (This assumes that
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pending RenderViewHost is still responsive.)
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (render_view_host_->is_waiting_for_unload_ack()) {
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The request has been started and paused while we're waiting for the
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // unload handler to finish.  We'll pretend that it did.  The pending
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // renderer will then be swapped in as part of the usual DidNavigate logic.
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // (If the unload handler later finishes, this call will be ignored because
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the pending_nav_params_ state will already be cleaned up.)
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    current_host()->OnSwappedOut(true);
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else if (render_view_host_->is_waiting_for_beforeunload_ack()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Haven't gotten around to starting the request, because we're still
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // waiting for the beforeunload handler to finish.  We'll pretend that it
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // did finish, to let the navigation proceed.  Note that there's a danger
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that the beforeunload handler will later finish and possibly return
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // false (meaning the navigation should not proceed), but we'll ignore it
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in this case because it took too long.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending_render_view_host_->are_navigations_suspended())
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pending_render_view_host_->SetNavigationsSuspended(
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          false, base::TimeTicks::Now());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) {
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Make sure this is from our current RVH, and that we have a pending
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // navigation from OnCrossSiteResponse.  (There may be no pending navigation
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // for data URLs that don't make network requests, for example.)   If not,
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // just return early and ignore.
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (render_view_host != render_view_host_ || !pending_nav_params_.get()) {
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pending_nav_params_.reset();
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Now that the unload handler has run, we need to either initiate the
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // pending transfer (if there is one) or resume the paused response (if not).
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(creis): The blank swapped out page is visible during this time, but
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // we can shorten this by delivering the response directly, rather than
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // forcing an identical request to be made.
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (pending_nav_params_->is_transfer) {
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Treat the last URL in the chain as the destination and the remainder as
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // the redirect chain.
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(pending_nav_params_->transfer_url_chain.size());
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GURL transfer_url = pending_nav_params_->transfer_url_chain.back();
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_nav_params_->transfer_url_chain.pop_back();
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // We don't know whether the original request had |user_action| set to true.
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // However, since we force the navigation to be in the current tab, it
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // doesn't matter.
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    render_view_host->GetDelegate()->RequestTransferURL(
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        transfer_url,
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        pending_nav_params_->transfer_url_chain,
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        pending_nav_params_->referrer,
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        pending_nav_params_->page_transition,
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        CURRENT_TAB,
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        pending_nav_params_->frame_id,
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        pending_nav_params_->global_request_id,
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        pending_nav_params_->should_replace_current_entry,
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        true);
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else if (pending_render_view_host_) {
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    RenderProcessHostImpl* pending_process =
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        static_cast<RenderProcessHostImpl*>(
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            pending_render_view_host_->GetProcess());
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pending_process->ResumeDeferredNavigation(
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        pending_nav_params_->global_request_id);
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pending_nav_params_.reset();
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::DidNavigateMainFrame(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHost* render_view_host) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cross_navigation_pending_) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_render_view_host_);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should only hear this from our current renderer.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(render_view_host == render_view_host_);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Even when there is no pending RVH, there may be a pending Web UI.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending_web_ui())
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommitPending();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_view_host == pending_render_view_host_) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The pending cross-site navigation completed, so show the renderer.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If it committed without sending network requests (e.g., data URLs),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then we still need to swap out the old RVH first and run its unload
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // handler.  OK for that to happen in the background.
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (pending_render_view_host_->HasPendingCrossSiteRequest())
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SwapOutOldPage();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommitPending();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cross_navigation_pending_ = false;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (render_view_host == render_view_host_) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A navigation in the original page has taken place.  Cancel the pending
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelPending();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cross_navigation_pending_ = false;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No one else should be sending us DidNavigate in this state.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(false);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify all swapped out hosts, including the pending RVH.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != swapped_out_hosts_.end();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_NE(iter->second->GetSiteInstance(),
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              current_host()->GetSiteInstance());
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    iter->second->DisownOpener();
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::RendererAbortedProvisionalLoad(
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHost* render_view_host) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We used to cancel the pending renderer here for cross-site downloads.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, it's not safe to do that because the download logic repeatedly
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // looks for this WebContents based on a render view ID.  Instead, we just
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // leave the pending renderer around until the next navigation event
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (Navigate, DidNavigate, etc), which will clean it up properly.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(creis): All of this will go away when we move the cross-site logic
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to ResourceDispatcherHost, so that we intercept responses rather than
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation events.  (That's necessary to support onunload anyway.)  Once
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we've made that change, we won't create a pending renderer until we know
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the response is not a download.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::RendererProcessClosing(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderProcessHost* render_process_host) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove any swapped out RVHs from this process, so that we don't try to
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // swap them back in while the process is exiting.  Start by finding them,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since there could be more than one.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<int> ids_to_remove;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != swapped_out_hosts_.end();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->second->GetProcess() == render_process_host)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ids_to_remove.push_back(iter->first);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete them.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!ids_to_remove.empty()) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    swapped_out_hosts_[ids_to_remove.back()]->Shutdown();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    swapped_out_hosts_.erase(ids_to_remove.back());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids_to_remove.pop_back();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::ShouldClosePage(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool for_cross_site_transition,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool proceed,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::TimeTicks& proceed_time) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (for_cross_site_transition) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ignore if we're not in a cross-site navigation.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cross_navigation_pending_)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (proceed) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ok to unload the current page, so proceed with the cross-site
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // navigation.  Note that if navigations are not currently suspended, it
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // might be because the renderer was deemed unresponsive and this call was
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // already made by ShouldCloseTabOnUnresponsiveRenderer.  In that case, it
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is ok to do nothing here.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pending_render_view_host_ &&
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          pending_render_view_host_->are_navigations_suspended()) {
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        pending_render_view_host_->SetNavigationsSuspended(false, proceed_time);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Current page says to cancel.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CancelPending();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cross_navigation_pending_ = false;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-cross site transition means closing the entire tab.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool proceed_to_fire_unload;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  &proceed_to_fire_unload);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (proceed_to_fire_unload) {
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // If we're about to close the tab and there's a pending RVH, cancel it.
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Otherwise, if the navigation in the pending RVH completes before the
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // close in the current RVH, we'll lose the tab close.
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (pending_render_view_host_) {
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        CancelPending();
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        cross_navigation_pending_ = false;
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is not a cross-site navigation, the tab is being closed.
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host_->ClosePage();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::OnCrossSiteResponse(
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    RenderViewHost* pending_render_view_host,
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GlobalRequestID& global_request_id,
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool is_transfer,
4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::vector<GURL>& transfer_url_chain,
4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const Referrer& referrer,
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    PageTransition page_transition,
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int64 frame_id,
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool should_replace_current_entry) {
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This should be called either when the pending RVH is ready to commit or
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // when we realize that the current RVH's request requires a transfer.
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_render_view_host == pending_render_view_host_ ||
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_render_view_host == render_view_host_);
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(creis): Eventually we will want to check all navigation responses
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // here, but currently we pass information for a transfer if
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // ShouldSwapProcessesForRedirect returned true in the network stack.
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // In that case, we should set up a transfer after the unload handler runs.
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If is_transfer is false, we will just run the unload handler and resume.
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  pending_nav_params_.reset(new PendingNavigationParams(
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      global_request_id, is_transfer, transfer_url_chain, referrer,
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      page_transition, frame_id, should_replace_current_entry));
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Run the unload handler of the current page.
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SwapOutOldPage();
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::SwapOutOldPage() {
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Should only see this while we have a pending renderer or transfer.
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(cross_navigation_pending_ || pending_nav_params_.get());
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Tell the renderer to suppress any further modal dialogs so that we can swap
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it out.  This must be done before canceling any current dialog, in case
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // there is a loop creating additional dialogs.
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  render_view_host_->SuppressDialogsUntilSwapOut();
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Now close any modal dialogs that would prevent us from swapping out.  This
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // no longer on the stack when we send the SwapOut message.
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delegate_->CancelModalDialogsForRenderManager();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell the old renderer it is being swapped out.  This will fire the unload
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handler (without firing the beforeunload handler a second time).  When the
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unload handler finishes and the navigation completes, we will send a
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // message to the ResourceDispatcherHost, allowing the pending RVH's response
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to resume.
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  render_view_host_->SwapOut();
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ResourceDispatcherHost has told us to run the onunload handler, which
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // means it is not a download or unsafe page, and we are going to perform the
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation.  Thus, we no longer need to remember that the RenderViewHost
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is part of a pending cross-site request.
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (pending_render_view_host_)
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::Observe(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NotificationSource& source,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NotificationDetails& details) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case NOTIFICATION_RENDERER_PROCESS_CLOSED:
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_RENDERER_PROCESS_CLOSING:
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RendererProcessClosing(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Source<RenderProcessHost>(source).ptr());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::ShouldTransitionCrossSite() {
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // False in the single-process mode, as it makes RVHs to accumulate
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // in swapped_out_hosts_.
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if we are using process-per-site-instance (default) or
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process-per-site (kProcessPerSite).
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) &&
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const NavigationEntry* current_entry,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NavigationEntryImpl* new_entry) const {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(new_entry);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If new_entry already has a SiteInstance, assume it is correct and use it.
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (new_entry->site_instance())
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for reasons to swap processes even if we are in a process model that
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // doesn't usually swap (e.g., process-per-tab).  Any time we return true,
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We use the effective URL here, since that's what is used in the
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SiteInstance's site and when we later call IsSameWebSite.  If there is no
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // current_entry, check the current SiteInstance's site, which might already
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // be committed to a Web UI URL (such as the NTP).
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserContext* browser_context =
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->GetControllerForRenderManager().GetBrowserContext();
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL& current_url = (current_entry) ?
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SiteInstanceImpl::GetEffectiveURL(browser_context,
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        current_entry->GetURL()) :
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      render_view_host_->GetSiteInstance()->GetSiteURL();
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                          new_entry->GetURL());
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
52481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  // Don't force a new BrowsingInstance for debug URLs that are handled in the
52581d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  // renderer process, like javascript: or chrome://crash.
52681d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  if (IsRendererDebugURL(new_url))
52781d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch    return false;
52881d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // For security, we should transition between processes when one is a Web UI
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // page and one isn't.
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser_context, current_url)) {
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If so, force a swap if destination is not an acceptable URL for Web UI.
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Here, data URLs are never allowed.
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            browser_context, new_url, false)) {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Force a swap if it's a Web UI URL.
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            browser_context, new_url)) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Check with the content client as well.  Important to pass current_url here,
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which uses the SiteInstance's site if there is no current_entry.
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (GetContentClient()->browser()->ShouldSwapBrowsingInstancesForNavigation(
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          render_view_host_->GetSiteInstance(), current_url, new_url)) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can't switch a RenderView between view source and non-view source mode
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without screwing up the session history sometimes (when navigating between
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it as a new navigation). So require a BrowsingInstance switch.
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (current_entry &&
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::ShouldReuseWebUI(
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const NavigationEntry* current_entry,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NavigationEntryImpl* new_entry) const {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller =
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->GetControllerForRenderManager();
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return current_entry && web_ui_.get() &&
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          controller.GetBrowserContext(), current_entry->GetURL()) ==
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          controller.GetBrowserContext(), new_entry->GetURL()));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry(
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NavigationEntryImpl& entry,
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SiteInstance* current_instance,
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool force_browsing_instance_swap) {
581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Determine which SiteInstance to use for navigating to |entry|.
582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const GURL& dest_url = entry.GetURL();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller =
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->GetControllerForRenderManager();
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserContext* browser_context = controller.GetBrowserContext();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If a swap is required, we need to force the SiteInstance AND
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // BrowsingInstance to be different ones, using CreateForURL.
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (force_browsing_instance_swap) {
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // We shouldn't be forcing a swap if an entry already has a SiteInstance.
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK(!entry.site_instance());
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return SiteInstance::CreateForURL(browser_context, dest_url);
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the entry has an instance already we should use it.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry.site_instance())
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return entry.site_instance();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (UGLY) HEURISTIC, process-per-site only:
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this navigation is generated, then it probably corresponds to a search
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // query.  Given that search results typically lead to users navigating to
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other sites, we don't really want to use the search engine hostname to
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // determine the site instance for this navigation.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: This can be removed once we have a way to transition between
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       RenderViews in response to a link click.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      PageTransitionCoreTypeIs(entry.GetTransitionType(),
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               PAGE_TRANSITION_GENERATED)) {
612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return current_instance;
6137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SiteInstanceImpl* current_site_instance =
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      static_cast<SiteInstanceImpl*>(current_instance);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for this entry.  We won't commit the SiteInstance to this site until the
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation commits (in DidNavigate), unless the navigation entry was
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // restored or it's a Web UI as described below.
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!current_site_instance->HasSite()) {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we've already created a SiteInstance for our destination, we don't
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // want to use this unused SiteInstance; use the existing one.  (We don't
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // do this check if the current_instance has a site, because for now, we
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // want to compare against the current URL and not the SiteInstance's site.
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // In this case, there is no current URL, so comparing against the site is
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // ok.  See additional comments below.)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also, if the URL should use process-per-site mode and there is an
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // existing process for the site, we should use it.  We can call
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GetRelatedSiteInstance() for this, which will eagerly set the site and
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // thus use the correct process.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool use_process_per_site =
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url);
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (current_site_instance->HasRelatedSiteInstance(dest_url) ||
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        use_process_per_site) {
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return current_site_instance->GetRelatedSiteInstance(dest_url);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For extensions, Web UI URLs (such as the new tab page), and apps we do
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // not want to use the current_instance if it has no site, since it will
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // have a RenderProcessHost of PRIV_NORMAL.  Create a new SiteInstance for
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // this URL instead (with the correct process type).
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (current_site_instance->HasWrongProcessForURL(dest_url))
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return current_site_instance->GetRelatedSiteInstance(dest_url);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // View-source URLs must use a new SiteInstance and BrowsingInstance.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nasko): This is the same condition as later in the function. This
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // should be taken into account when refactoring this method as part of
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://crbug.com/123007.
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.IsViewSourceMode())
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return SiteInstance::CreateForURL(browser_context, dest_url);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we are navigating from a blank SiteInstance to a WebUI, make sure we
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // create a new SiteInstance.
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser_context, dest_url)) {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SiteInstance::CreateForURL(browser_context, dest_url);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Normally the "site" on the SiteInstance is set lazily when the load
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // actually commits. This is to support better process sharing in case
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the site redirects to some other site: we want to use the destination
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // site in the site instance.
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In the case of session restore, as it loads all the pages immediately
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we need to set the site first, otherwise after a restore none of the
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pages would share renderers in process-per-site.
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE)
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      current_site_instance->SetSite(dest_url);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return current_site_instance;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Otherwise, only create a new SiteInstance for a cross-site navigation.
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(creis): Once we intercept links and script-based navigations, we
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be able to enforce that all entries in a SiteInstance actually have
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the same site, and it will be safe to compare the URL against the
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SiteInstance's site, as follows:
683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // const GURL& current_url = current_instance->site();
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For now, though, we're in a hybrid model where you only switch
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SiteInstances if you type in a cross-site URL.  This means we have to
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compare the entry's URL to the last committed entry's URL.
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NavigationEntry* current_entry = controller.GetLastCommittedEntry();
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (interstitial_page_) {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The interstitial is currently the last committed entry, but we want to
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compare against the last non-interstitial entry.
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    current_entry = controller.GetEntryAtOffset(-1);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If there is no last non-interstitial entry (and current_instance already
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has a site), then we must have been opened from another tab.  We want
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to compare against the URL of the page that opened us, but we can't
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get to it directly.  The best we can do is check against the site of
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the SiteInstance.  This will be correct when we intercept links and
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // script-based navigations, but for now, it could place some pages in a
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new process unnecessarily.  We should only hit this case if a page tries
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to open a new tab to an interstitial-inducing URL, and then navigates
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the page to a different same-site URL.  (This seems very unlikely in
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // practice.)
703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL& current_url = (current_entry) ? current_entry->GetURL() :
704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      current_instance->GetSiteURL();
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View-source URLs must use a new SiteInstance and BrowsingInstance.
70781d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  // We don't need a swap when going from view-source to a debug URL like
70881d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  // chrome://crash, however.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(creis): Refactor this method so this duplicated code isn't needed.
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See http://crbug.com/123007.
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (current_entry &&
71281d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch      current_entry->IsViewSourceMode() != entry.IsViewSourceMode() &&
71381d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch      !IsRendererDebugURL(dest_url)) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SiteInstance::CreateForURL(browser_context, dest_url);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the current SiteInstance for same site navigations, as long as the
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process type is correct.  (The URL may have been installed as an app since
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the last time we visited it.)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      !current_site_instance->HasWrongProcessForURL(dest_url)) {
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return current_instance;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Start the new renderer in a new SiteInstance, but in the current
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // BrowsingInstance.  It is important to immediately give this new
727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SiteInstance to a RenderViewHost (if it is different than our current
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SiteInstance), so that it is ref counted.  This will happen in
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // CreateRenderView.
730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return current_instance->GetRelatedSiteInstance(dest_url);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int RenderFrameHostManager::CreateRenderView(
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SiteInstance* instance,
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int opener_route_id,
7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool swapped_out,
7373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool hidden) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(instance);
7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We are creating a pending or swapped out RVH here.  We should never create
742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it in the same SiteInstance as our current RVH.
743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK_NE(render_view_host_->GetSiteInstance(), instance);
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if we've already created an RVH for this SiteInstance.  If so, try
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to re-use the existing one, which has already been initialized.  We'll
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remove it from the list of swapped out hosts if it commits.
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostImpl* new_render_view_host = static_cast<RenderViewHostImpl*>(
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSwappedOutRenderViewHost(instance));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_render_view_host) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Prevent the process from exiting while we're trying to use it.
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!swapped_out)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_render_view_host->GetProcess()->AddPendingView();
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a new RenderViewHost if we don't find an existing one.
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_render_view_host = static_cast<RenderViewHostImpl*>(
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RenderViewHostFactory::Create(instance,
758a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                      render_view_delegate_,
759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      render_frame_delegate_,
760a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                      render_widget_delegate_,
761a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                      MSG_ROUTING_NONE,
762a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                      MSG_ROUTING_NONE,
7633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                      swapped_out,
7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                      hidden));
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the new RVH is swapped out already, store it.  Otherwise prevent the
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process from exiting while we're trying to navigate in it.
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (swapped_out) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      swapped_out_hosts_[instance->GetId()] = new_render_view_host;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_render_view_host->GetProcess()->AddPendingView();
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = InitRenderView(new_render_view_host, opener_route_id);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (success) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't show the view until we get a DidNavigate from it.
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_render_view_host->GetView()->Hide();
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (!swapped_out) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CancelPending();
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use this as our new pending RVH if it isn't swapped out.
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!swapped_out)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host_ = new_render_view_host;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new_render_view_host->GetRoutingID();
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                            int opener_route_id) {
79268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // If the pending navigation is to a WebUI and the RenderView is not in a
79368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // guest process, tell the RenderView about any bindings it will need enabled.
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_host->AllowBindings(pending_web_ui()->GetBindings());
796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // process unless it's swapped out.
799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderViewHostImpl* rvh_impl =
800a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        static_cast<RenderViewHostImpl*>(render_view_host);
801a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!rvh_impl->is_swapped_out()) {
802a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
803a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                render_view_host->GetProcess()->GetID()));
804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delegate_->CreateRenderViewForRenderManager(render_view_host,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     opener_route_id);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::CommitPending() {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First check whether we're going to want to focus the location bar after
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this commit.  We do this now because the navigation hasn't formally
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // committed yet, so if we've already cleared |pending_web_ui_| the call chain
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this triggers won't be able to figure out what's going on.
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // We expect SwapOutOldPage to have canceled any modal dialogs and told the
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // renderer to suppress any further dialogs until it is swapped out.  However,
820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // crash reports indicate that it's still possible for modal dialogs to exist
821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // at this point, which poses a risk if we delete their RenderViewHost below.
822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Cancel them again to be safe.  http://crbug.com/324320.
823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->CancelModalDialogsForRenderManager();
824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next commit the Web UI, if any. Either replace |web_ui_| with
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // leave |web_ui_| as is if reusing it.
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
82933bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch  if (pending_web_ui_) {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui_.reset(pending_web_ui_.release());
83133bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch  } else if (!pending_and_current_web_ui_.get()) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui_.reset();
83333bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch  } else {
83433bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch    DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
83533bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch    pending_and_current_web_ui_.reset();
83633bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch  }
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's possible for the pending_render_view_host_ to be NULL when we aren't
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // crossing process boundaries. If so, we just needed to handle the Web UI
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // committing above and we're done.
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_render_view_host_) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (will_focus_location_bar)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->SetFocusToLocationBar(false);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remember if the page was focused so we can focus the new renderer in
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that case.
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool focus_render_view = !will_focus_location_bar &&
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host_->GetView() && render_view_host_->GetView()->HasFocus();
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Swap in the pending view and make it active. Also ensure the FrameTree
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // stays in sync.
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostImpl* old_render_view_host = render_view_host_;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_ = pending_render_view_host_;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_render_view_host_ = NULL;
8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  render_view_host_->AttachToFrameTree();
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The process will no longer try to exit, so we can decrement the count.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view_host_->GetProcess()->RemovePendingView();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // If the view is gone, then this RenderViewHost died while it was hidden.
86368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // We ignored the RenderProcessGone call at the time, so we should send it now
86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // to make sure the sad tab shows up, etc.
86568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!render_view_host_->GetView())
86668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delegate_->RenderProcessGoneFromRenderManager(render_view_host_);
86768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  else if (!delegate_->IsHidden())
86868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    render_view_host_->GetView()->Show();
86968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Hide the old view now that the new one is visible.
8714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (old_render_view_host->GetView()) {
8724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    old_render_view_host->GetView()->Hide();
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    old_render_view_host->WasSwappedOut();
8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the size is up to date.  (Fix for bug 1079768.)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->UpdateRenderViewSizeForRenderManager();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (will_focus_location_bar)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->SetFocusToLocationBar(false);
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (focus_render_view && render_view_host_->GetView())
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostViewPort::FromRWHV(render_view_host_->GetView())->Focus();
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify that we've swapped RenderViewHosts. We do this
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // before shutting down the RVH so that we can clean up
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // RendererResources related to the RVH first.
8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delegate_->NotifySwappedFromRenderManager(old_render_view_host,
8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                            render_view_host_);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the pending view was on the swapped out list, we can remove it.
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  swapped_out_hosts_.erase(render_view_host_->GetSiteInstance()->GetId());
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If there are no active RVHs in this SiteInstance, it means that
8947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // this RVH was the last active one in the SiteInstance. Now that we
8957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // know that all RVHs are swapped out, we can delete all the RVHs in
8967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // this SiteInstance.
8977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!static_cast<SiteInstanceImpl*>(old_render_view_host->GetSiteInstance())->
8987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          active_view_count()) {
8997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ShutdownRenderViewHostsInSiteInstance(
9007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        old_render_view_host->GetSiteInstance()->GetId());
9017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // This is deleted while cleaning up the SitaInstance's views.
9027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    old_render_view_host = NULL;
9037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else if (old_render_view_host->IsRenderViewLive()) {
9047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // If the old RVH is live, we are swapping it out and should keep track of
9057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // it in case we navigate back to it.
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(old_render_view_host->is_swapped_out());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sure we don't get different rvh instances for the same site instance
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in the same rvhmgr.
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(creis): Clean this up.
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 old_site_instance_id =
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_render_view_host->GetSiteInstance()->GetId();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostMap::iterator iter =
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        swapped_out_hosts_.find(old_site_instance_id);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter != swapped_out_hosts_.end() &&
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        iter->second != old_render_view_host) {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Shutdown the RVH that will be replaced in the map to avoid a leak.
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter->second->Shutdown();
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    swapped_out_hosts_[old_site_instance_id] = old_render_view_host;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_render_view_host->Shutdown();
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    old_render_view_host = NULL;  // Shutdown() deletes it.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::ShutdownRenderViewHostsInSiteInstance(
9287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int32 site_instance_id) {
9297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // First remove any swapped out RVH for this SiteInstance from our
9307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // list.
9317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  swapped_out_hosts_.erase(site_instance_id);
9327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
93358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<RenderWidgetHostIterator> widgets(
93458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RenderWidgetHostImpl::GetAllRenderWidgetHosts());
93558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  while (RenderWidgetHost* widget = widgets->GetNextHost()) {
93658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!widget->IsRenderView())
9377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      continue;
9387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    RenderViewHostImpl* rvh =
93958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget));
94058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (site_instance_id == rvh->GetSiteInstance()->GetId())
94158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      rvh->Shutdown();
9427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderViewHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NavigationEntryImpl& entry) {
947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If we are currently navigating cross-process, we want to get back to normal
948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // and then navigate as usual.
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cross_navigation_pending_) {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending_render_view_host_)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CancelPending();
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cross_navigation_pending_ = false;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // render_view_host_'s SiteInstance and new_instance will not be deleted
956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // before the end of this method, so we don't have to worry about their ref
957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // counts dropping to zero.
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SiteInstance* current_instance = render_view_host_->GetSiteInstance();
959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SiteInstance* new_instance = current_instance;
960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We do not currently swap processes for navigations in webview tag guests.
962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Determine if we need a new BrowsingInstance for this entry.  If true, this
965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // implies that it will get a new SiteInstance (and likely process), and that
966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // other tabs in the current BrosingInstance will be unalbe to script it.
967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This is used for cases that require a process swap even in the
968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // process-per-tab model, such as WebUI pages.
969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const NavigationEntry* current_entry =
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->GetLastCommittedNavigationEntryForRenderManager();
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool force_swap = !is_guest_scheme &&
972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap))
974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If force_swap is true, we must use a different SiteInstance.  If we didn't,
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // we would have two RenderViewHosts in the same SiteInstance and the same
978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // tab, resulting in page_id conflicts for their NavigationEntries.
979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (force_swap)
980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK_NE(new_instance, current_instance);
981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (new_instance != current_instance) {
983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // New SiteInstance: create a pending RVH to navigate.
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!cross_navigation_pending_);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This will possibly create (set to NULL) a Web UI object for the pending
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // page. We'll use this later to give the page special access. This must
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // happen before the new renderer is created below so it will get bindings.
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It must also happen after the above conditional call to CancelPending(),
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // otherwise CancelPending may clear the pending_web_ui_ and the page will
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // not have its bindings set appropriately.
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetPendingWebUI(entry);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure that we have created RVHs for the new RVH's opener chain if
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we are staying in the same BrowsingInstance. This allows the pending RVH
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to send cross-process script calls to its opener(s).
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int opener_route_id = MSG_ROUTING_NONE;
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (new_instance->IsRelatedSiteInstance(current_instance)) {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      opener_route_id =
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a non-swapped-out pending RVH with the given opener and navigate
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it.
10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int route_id = CreateRenderView(new_instance, opener_route_id, false,
10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    delegate_->IsHidden());
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (route_id == MSG_ROUTING_NONE)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if our current RVH is live before we set up a transition.
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!render_view_host_->IsRenderViewLive()) {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!cross_navigation_pending_) {
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // The current RVH is not live.  There's no reason to sit around with a
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // sad tab or a newly created RVH while we wait for the pending RVH to
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // navigate.  Just switch to the pending RVH now and go back to non
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // cross-navigating (Note that we don't care about on{before}unload
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // handlers if the current RVH isn't live.)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CommitPending();
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return render_view_host_;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return render_view_host_;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, it's safe to treat this as a pending cross-site transition.
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We need to wait until the beforeunload handler has run, unless we are
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // transferring an existing request (in which case it has already run).
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Suspend the new render view (i.e., don't let it send the cross-site
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Navigate message) until we hear back from the old renderer's
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // beforeunload handler.  If the handler returns false, we'll have to
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cancel the request.
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_render_view_host_->are_navigations_suspended());
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool is_transfer =
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry.transferred_global_request_id() != GlobalRequestID();
10364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (is_transfer) {
10374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // We don't need to stop the old renderer or run beforeunload/unload
10384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // handlers, because those have already been done.
10394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      DCHECK(pending_nav_params_->global_request_id ==
10404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                entry.transferred_global_request_id());
10414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Also make sure the old render view stops, in case a load is in
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // progress.  (We don't want to do this for transfers, since it will
1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // interrupt the transfer with an unexpected DidStopLoading.)
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      render_view_host_->Send(
1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          new ViewMsg_Stop(render_view_host_->GetRoutingID()));
1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pending_render_view_host_->SetNavigationsSuspended(true,
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                         base::TimeTicks());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
10524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // request, so that ResourceDispatcherHost will know to tell us to run the
10534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // old page's unload handler before it sends the response.
10544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
10554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We now have a pending RVH.
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!cross_navigation_pending_);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cross_navigation_pending_ = true;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Unless we are transferring an existing request, we should now
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tell the old render view to run its beforeunload handler, since it
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // doesn't otherwise know that the cross-site request is happening.  This
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will trigger a call to ShouldClosePage with the reply.
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!is_transfer)
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      render_view_host_->FirePageBeforeUnload(true);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pending_render_view_host_;
1069f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1071f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Otherwise the same SiteInstance can be used.  Navigate render_view_host_.
1072f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!cross_navigation_pending_);
1073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ShouldReuseWebUI(current_entry, &entry)) {
1074f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    pending_web_ui_.reset();
1075f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1077f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SetPendingWebUI(entry);
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1079f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure the new RenderViewHost has the right bindings.
1080f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (pending_web_ui() && !render_view_host_->GetProcess()->IsGuest())
1081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      render_view_host_->AllowBindings(pending_web_ui()->GetBindings());
1082f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1084f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (pending_web_ui() && render_view_host_->IsRenderViewLive())
1085f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1087f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The renderer can exit view source mode when any error or cancellation
1088f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // happen. We must overwrite to recover the mode.
1089f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (entry.IsViewSourceMode()) {
1090f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    render_view_host_->Send(
1091f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return render_view_host_;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::CancelPending() {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostImpl* pending_render_view_host = pending_render_view_host_;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_render_view_host_ = NULL;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_render_view_host,
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host_);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We no longer need to prevent the process from exiting.
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_render_view_host->GetProcess()->RemovePendingView();
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending RVH may already be on the swapped out list if we started to
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // swap it back in and then canceled.  If so, make sure it gets swapped out
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // again.  If it's not on the swapped out list (e.g., aborting a pending
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // load), then it's safe to shut down.
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsOnSwappedOutList(pending_render_view_host)) {
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Any currently suspended navigations are no longer needed.
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host->CancelSuspendedNavigations();
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pending_render_view_host->SwapOut();
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We won't be coming back, so shut this one down.
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host->Shutdown();
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_web_ui_.reset();
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_and_current_web_ui_.reset();
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) {
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are doing this in order to work around and to track a crasher
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (http://crbug.com/23411) where it seems that pending_render_view_host_ is
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted (not sure from where) but not NULLed.
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rvh == pending_render_view_host_) {
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If you hit this NOTREACHED, please report it in the following bug
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://crbug.com/23411 Make sure to include what you were doing when it
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // happened  (navigating to a new page, closing a tab...) and if you can
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reproduce.
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_render_view_host_ = NULL;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure deleted RVHs are not kept in the swapped out list while we are
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // still alive.  (If render_view_host_ is null, we're already being deleted.)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!render_view_host_)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can't look it up by SiteInstance ID, which may no longer be valid.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != swapped_out_hosts_.end();
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->second == rvh) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      swapped_out_hosts_.erase(iter);
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool RenderFrameHostManager::IsOnSwappedOutList(RenderViewHost* rvh) const {
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rvh->GetSiteInstance())
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RenderViewHostMap::const_iterator iter = swapped_out_hosts_.find(
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      rvh->GetSiteInstance()->GetId());
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter == swapped_out_hosts_.end())
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return iter->second == rvh;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SiteInstance* instance) {
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter != swapped_out_hosts_.end())
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return iter->second;
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1176