Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/frame_host/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_host_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "content/browser/child_process_security_policy_impl.h" | 12 #include "content/browser/child_process_security_policy_impl.h" |
| 13 #include "content/browser/devtools/render_view_devtools_agent_host.h" | 13 #include "content/browser/devtools/render_view_devtools_agent_host.h" |
| 14 #include "content/browser/frame_host/cross_process_frame_connector.h" | 14 #include "content/browser/frame_host/cross_process_frame_connector.h" |
| 15 #include "content/browser/frame_host/cross_site_transferring_request.h" | 15 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 16 #include "content/browser/frame_host/debug_urls.h" | 16 #include "content/browser/frame_host/debug_urls.h" |
| 17 #include "content/browser/frame_host/interstitial_page_impl.h" | 17 #include "content/browser/frame_host/interstitial_page_impl.h" |
| 18 #include "content/browser/frame_host/navigation_controller_impl.h" | 18 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 19 #include "content/browser/frame_host/navigation_entry_impl.h" | 19 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 20 #include "content/browser/frame_host/navigator.h" | 20 #include "content/browser/frame_host/navigator.h" |
| 21 #include "content/browser/frame_host/render_frame_host_factory.h" | 21 #include "content/browser/frame_host/render_frame_host_factory.h" |
| 22 #include "content/browser/frame_host/render_frame_host_impl.h" | 22 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 23 #include "content/browser/frame_host/render_frame_proxy_host.h" | |
| 23 #include "content/browser/renderer_host/render_process_host_impl.h" | 24 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 24 #include "content/browser/renderer_host/render_view_host_factory.h" | 25 #include "content/browser/renderer_host/render_view_host_factory.h" |
| 25 #include "content/browser/renderer_host/render_view_host_impl.h" | 26 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 26 #include "content/browser/site_instance_impl.h" | 27 #include "content/browser/site_instance_impl.h" |
| 27 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 28 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 28 #include "content/browser/webui/web_ui_impl.h" | 29 #include "content/browser/webui/web_ui_impl.h" |
| 29 #include "content/common/view_messages.h" | 30 #include "content/common/view_messages.h" |
| 30 #include "content/port/browser/render_widget_host_view_port.h" | 31 #include "content/port/browser/render_widget_host_view_port.h" |
| 31 #include "content/public/browser/content_browser_client.h" | 32 #include "content/public/browser/content_browser_client.h" |
| 32 #include "content/public/browser/notification_service.h" | 33 #include "content/public/browser/notification_service.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 RenderFrameHostManager::~RenderFrameHostManager() { | 83 RenderFrameHostManager::~RenderFrameHostManager() { |
| 83 if (pending_render_frame_host_) | 84 if (pending_render_frame_host_) |
| 84 CancelPending(); | 85 CancelPending(); |
| 85 | 86 |
| 86 if (cross_process_frame_connector_) | 87 if (cross_process_frame_connector_) |
| 87 delete cross_process_frame_connector_; | 88 delete cross_process_frame_connector_; |
| 88 | 89 |
| 89 // We should always have a current RenderFrameHost except in some tests. | 90 // We should always have a current RenderFrameHost except in some tests. |
| 90 render_frame_host_.reset(); | 91 render_frame_host_.reset(); |
| 91 | 92 |
| 92 // TODO(creis): Now that we aren't using Shutdown, make RenderFrameHostMap | |
| 93 // use scoped_ptrs. | |
| 94 // Delete any swapped out RenderFrameHosts. | 93 // Delete any swapped out RenderFrameHosts. |
| 95 for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin(); | 94 for (RenderFrameHostMap::iterator iter = proxy_hosts_.begin(); |
| 96 iter != swapped_out_hosts_.end(); | 95 iter != proxy_hosts_.end(); |
| 97 ++iter) { | 96 ++iter) { |
| 98 delete iter->second; | 97 delete iter->second; |
| 99 } | 98 } |
| 100 } | 99 } |
| 101 | 100 |
| 102 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 101 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
| 103 SiteInstance* site_instance, | 102 SiteInstance* site_instance, |
| 104 int view_routing_id, | 103 int view_routing_id, |
| 105 int frame_routing_id) { | 104 int frame_routing_id) { |
| 106 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It | 105 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It |
| 107 // is important to immediately give this SiteInstance to a RenderViewHost so | 106 // is important to immediately give this SiteInstance to a RenderViewHost so |
| 108 // that the SiteInstance is ref counted. | 107 // that the SiteInstance is ref counted. |
| 109 if (!site_instance) | 108 if (!site_instance) |
| 110 site_instance = SiteInstance::Create(browser_context); | 109 site_instance = SiteInstance::Create(browser_context); |
| 111 | 110 |
| 112 render_frame_host_ = make_scoped_ptr( | 111 render_frame_host_ = CreateRenderFrameHost(site_instance, |
| 113 CreateRenderFrameHost(site_instance, view_routing_id, frame_routing_id, | 112 view_routing_id, |
| 114 false, delegate_->IsHidden())); | 113 frame_routing_id, |
| 114 false, | |
| 115 delegate_->IsHidden()); | |
| 115 | 116 |
| 116 // Keep track of renderer processes as they start to shut down or are | 117 // Keep track of renderer processes as they start to shut down or are |
| 117 // crashed/killed. | 118 // crashed/killed. |
| 118 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, | 119 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 119 NotificationService::AllSources()); | 120 NotificationService::AllSources()); |
| 120 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSING, | 121 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSING, |
| 121 NotificationService::AllSources()); | 122 NotificationService::AllSources()); |
| 122 } | 123 } |
| 123 | 124 |
| 124 RenderViewHostImpl* RenderFrameHostManager::current_host() const { | 125 RenderViewHostImpl* RenderFrameHostManager::current_host() const { |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 cross_navigation_pending_ = false; | 441 cross_navigation_pending_ = false; |
| 441 } else { | 442 } else { |
| 442 // No one else should be sending us DidNavigate in this state. | 443 // No one else should be sending us DidNavigate in this state. |
| 443 DCHECK(false); | 444 DCHECK(false); |
| 444 } | 445 } |
| 445 } | 446 } |
| 446 | 447 |
| 447 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers. | 448 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers. |
| 448 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) { | 449 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) { |
| 449 // Notify all swapped out hosts, including the pending RVH. | 450 // Notify all swapped out hosts, including the pending RVH. |
| 450 for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin(); | 451 for (RenderFrameHostMap::iterator iter = proxy_hosts_.begin(); |
| 451 iter != swapped_out_hosts_.end(); | 452 iter != proxy_hosts_.end(); |
| 452 ++iter) { | 453 ++iter) { |
| 453 DCHECK_NE(iter->second->GetSiteInstance(), | 454 DCHECK_NE(iter->second->render_frame_host()->GetSiteInstance(), |
|
Charlie Reis
2014/04/09 21:48:30
I think it would make sense to put a GetSiteInstan
nasko
2014/04/10 20:37:36
Done.
| |
| 454 current_frame_host()->GetSiteInstance()); | 455 current_frame_host()->GetSiteInstance()); |
| 455 iter->second->render_view_host()->DisownOpener(); | 456 iter->second->render_view_host()->DisownOpener(); |
| 456 } | 457 } |
| 457 } | 458 } |
| 458 | 459 |
| 459 void RenderFrameHostManager::RendererProcessClosing( | 460 void RenderFrameHostManager::RendererProcessClosing( |
| 460 RenderProcessHost* render_process_host) { | 461 RenderProcessHost* render_process_host) { |
| 461 // Remove any swapped out RVHs from this process, so that we don't try to | 462 // Remove any swapped out RVHs from this process, so that we don't try to |
| 462 // swap them back in while the process is exiting. Start by finding them, | 463 // swap them back in while the process is exiting. Start by finding them, |
| 463 // since there could be more than one. | 464 // since there could be more than one. |
| 464 std::list<int> ids_to_remove; | 465 std::list<int> ids_to_remove; |
| 465 for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin(); | 466 for (RenderFrameHostMap::iterator iter = proxy_hosts_.begin(); |
| 466 iter != swapped_out_hosts_.end(); | 467 iter != proxy_hosts_.end(); |
| 467 ++iter) { | 468 ++iter) { |
| 468 if (iter->second->GetProcess() == render_process_host) | 469 if (iter->second->GetProcess() == render_process_host) |
| 469 ids_to_remove.push_back(iter->first); | 470 ids_to_remove.push_back(iter->first); |
| 470 } | 471 } |
| 471 | 472 |
| 472 // Now delete them. | 473 // Now delete them. |
| 473 while (!ids_to_remove.empty()) { | 474 while (!ids_to_remove.empty()) { |
| 474 delete swapped_out_hosts_[ids_to_remove.back()]; | 475 delete proxy_hosts_[ids_to_remove.back()]; |
| 475 swapped_out_hosts_.erase(ids_to_remove.back()); | 476 proxy_hosts_.erase(ids_to_remove.back()); |
| 476 ids_to_remove.pop_back(); | 477 ids_to_remove.pop_back(); |
| 477 } | 478 } |
| 478 } | 479 } |
| 479 | 480 |
| 480 void RenderFrameHostManager::SwapOutOldPage() { | 481 void RenderFrameHostManager::SwapOutOldPage() { |
| 481 // Should only see this while we have a pending renderer or transfer. | 482 // Should only see this while we have a pending renderer or transfer. |
| 482 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); | 483 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); |
| 483 | 484 |
| 484 // Tell the renderer to suppress any further modal dialogs so that we can swap | 485 // Tell the renderer to suppress any further modal dialogs so that we can swap |
| 485 // it out. This must be done before canceling any current dialog, in case | 486 // it out. This must be done before canceling any current dialog, in case |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 case NOTIFICATION_RENDERER_PROCESS_CLOSING: | 542 case NOTIFICATION_RENDERER_PROCESS_CLOSING: |
| 542 RendererProcessClosing( | 543 RendererProcessClosing( |
| 543 Source<RenderProcessHost>(source).ptr()); | 544 Source<RenderProcessHost>(source).ptr()); |
| 544 break; | 545 break; |
| 545 | 546 |
| 546 default: | 547 default: |
| 547 NOTREACHED(); | 548 NOTREACHED(); |
| 548 } | 549 } |
| 549 } | 550 } |
| 550 | 551 |
| 551 bool RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance( | 552 bool RenderFrameHostManager::ClearProxiesInSiteInstance( |
| 552 int32 site_instance_id, | 553 int32 site_instance_id, |
| 553 FrameTreeNode* node) { | 554 FrameTreeNode* node) { |
| 554 RenderFrameHostMap::iterator iter = | 555 RenderFrameHostMap::iterator iter = |
| 555 node->render_manager()->swapped_out_hosts_.find(site_instance_id); | 556 node->render_manager()->proxy_hosts_.find(site_instance_id); |
| 556 if (iter != node->render_manager()->swapped_out_hosts_.end()) { | 557 if (iter != node->render_manager()->proxy_hosts_.end()) { |
| 557 RenderFrameHostImpl* swapped_out_rfh = iter->second; | 558 RenderFrameProxyHost* proxy = iter->second; |
| 558 // If the RVH is pending swap out, it needs to switch state to | 559 // If the RVH is pending swap out, it needs to switch state to |
| 559 // pending shutdown. Otherwise it is deleted. | 560 // pending shutdown. Otherwise it is deleted. |
| 560 if (swapped_out_rfh->render_view_host()->rvh_state() == | 561 if (proxy->render_view_host()->rvh_state() == |
| 561 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { | 562 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { |
| 562 swapped_out_rfh->SetPendingShutdown(base::Bind( | 563 scoped_ptr<RenderFrameHostImpl> rfh = proxy->PassFrameHost(); |
|
Charlie Reis
2014/04/09 21:48:30
nit: I liked the swapped_out_rfh name from before.
nasko
2014/04/10 20:37:36
Done.
| |
| 564 | |
| 565 rfh->SetPendingShutdown(base::Bind( | |
| 563 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | 566 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, |
| 564 node->render_manager()->weak_factory_.GetWeakPtr(), | 567 node->render_manager()->weak_factory_.GetWeakPtr(), |
| 565 site_instance_id, | 568 site_instance_id, |
| 566 swapped_out_rfh)); | 569 rfh.get())); |
| 567 RFHPendingDeleteMap::iterator pending_delete_iter = | 570 RFHPendingDeleteMap::iterator pending_delete_iter = |
| 568 node->render_manager()->pending_delete_hosts_.find(site_instance_id); | 571 node->render_manager()->pending_delete_hosts_.find(site_instance_id); |
| 569 if (pending_delete_iter == | 572 if (pending_delete_iter == |
| 570 node->render_manager()->pending_delete_hosts_.end() || | 573 node->render_manager()->pending_delete_hosts_.end() || |
| 571 pending_delete_iter->second.get() != iter->second) { | 574 pending_delete_iter->second.get() != rfh) { |
| 572 node->render_manager()->pending_delete_hosts_[site_instance_id] = | 575 node->render_manager()->pending_delete_hosts_[site_instance_id] = |
| 573 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh); | 576 linked_ptr<RenderFrameHostImpl>(rfh.release()); |
| 574 } | 577 } |
| 575 } else { | 578 } else { |
| 576 delete swapped_out_rfh; | 579 delete proxy; |
| 577 } | 580 } |
| 578 node->render_manager()->swapped_out_hosts_.erase(site_instance_id); | 581 node->render_manager()->proxy_hosts_.erase(site_instance_id); |
| 579 } | 582 } |
| 580 | 583 |
| 581 return true; | 584 return true; |
| 582 } | 585 } |
| 583 | 586 |
| 584 bool RenderFrameHostManager::ShouldTransitionCrossSite() { | 587 bool RenderFrameHostManager::ShouldTransitionCrossSite() { |
| 585 // False in the single-process mode, as it makes RVHs to accumulate | 588 // False in the single-process mode, as it makes RVHs to accumulate |
| 586 // in swapped_out_hosts_. | 589 // in swapped_out_hosts_. |
| 587 // True if we are using process-per-site-instance (default) or | 590 // True if we are using process-per-site-instance (default) or |
| 588 // process-per-site (kProcessPerSite). | 591 // process-per-site (kProcessPerSite). |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 } | 829 } |
| 827 | 830 |
| 828 // Start the new renderer in a new SiteInstance, but in the current | 831 // Start the new renderer in a new SiteInstance, but in the current |
| 829 // BrowsingInstance. It is important to immediately give this new | 832 // BrowsingInstance. It is important to immediately give this new |
| 830 // SiteInstance to a RenderViewHost (if it is different than our current | 833 // SiteInstance to a RenderViewHost (if it is different than our current |
| 831 // SiteInstance), so that it is ref counted. This will happen in | 834 // SiteInstance), so that it is ref counted. This will happen in |
| 832 // CreateRenderView. | 835 // CreateRenderView. |
| 833 return current_instance->GetRelatedSiteInstance(dest_url); | 836 return current_instance->GetRelatedSiteInstance(dest_url); |
| 834 } | 837 } |
| 835 | 838 |
| 836 RenderFrameHostImpl* RenderFrameHostManager::CreateRenderFrameHost( | 839 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( |
| 837 SiteInstance* site_instance, | 840 SiteInstance* site_instance, |
| 838 int view_routing_id, | 841 int view_routing_id, |
| 839 int frame_routing_id, | 842 int frame_routing_id, |
| 840 bool swapped_out, | 843 bool swapped_out, |
| 841 bool hidden) { | 844 bool hidden) { |
| 842 if (frame_routing_id == MSG_ROUTING_NONE) | 845 if (frame_routing_id == MSG_ROUTING_NONE) |
| 843 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 846 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
| 844 | 847 |
| 845 // Create a RVH for main frames, or find the existing one for subframes. | 848 // Create a RVH for main frames, or find the existing one for subframes. |
| 846 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 849 FrameTree* frame_tree = frame_tree_node_->frame_tree(); |
| 847 RenderViewHostImpl* render_view_host = NULL; | 850 RenderViewHostImpl* render_view_host = NULL; |
| 848 if (frame_tree_node_->IsMainFrame()) { | 851 if (frame_tree_node_->IsMainFrame()) { |
| 849 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( | 852 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( |
| 850 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); | 853 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); |
| 851 } else { | 854 } else { |
| 852 render_view_host = frame_tree->GetRenderViewHostForSubFrame(site_instance); | 855 render_view_host = frame_tree->GetRenderViewHostForSubFrame(site_instance); |
| 853 | 856 |
| 854 // If we haven't found a RVH for a subframe RFH, it's because we currently | 857 // If we haven't found a RVH for a subframe RFH, it's because we currently |
| 855 // do not create top-level RFHs for pending subframe navigations. Create | 858 // do not create top-level RFHs for pending subframe navigations. Create |
| 856 // the RVH here for now. | 859 // the RVH here for now. |
| 857 // TODO(creis): Mirror the frame tree so this check isn't necessary. | 860 // TODO(creis): Mirror the frame tree so this check isn't necessary. |
| 858 if (!render_view_host) { | 861 if (!render_view_host) { |
| 859 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( | 862 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( |
| 860 site_instance, view_routing_id, frame_routing_id, swapped_out, | 863 site_instance, view_routing_id, frame_routing_id, swapped_out, |
| 861 hidden); | 864 hidden); |
| 862 } | 865 } |
| 863 } | 866 } |
| 864 | 867 |
| 865 // TODO(creis): Make render_frame_host a scoped_ptr. | |
| 866 // TODO(creis): Pass hidden to RFH. | 868 // TODO(creis): Pass hidden to RFH. |
| 867 RenderFrameHostImpl* render_frame_host = | 869 scoped_ptr<RenderFrameHostImpl> render_frame_host = |
| 868 RenderFrameHostFactory::Create(render_view_host, | 870 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host, |
| 869 render_frame_delegate_, | 871 render_frame_delegate_, |
| 870 frame_tree, | 872 frame_tree, |
| 871 frame_tree_node_, | 873 frame_tree_node_, |
| 872 frame_routing_id, | 874 frame_routing_id, |
| 873 swapped_out).release(); | 875 swapped_out).release()); |
| 874 return render_frame_host; | 876 return render_frame_host.Pass(); |
| 875 } | 877 } |
| 876 | 878 |
| 877 int RenderFrameHostManager::CreateRenderFrame( | 879 int RenderFrameHostManager::CreateRenderFrame( |
| 878 SiteInstance* instance, | 880 SiteInstance* instance, |
| 879 int opener_route_id, | 881 int opener_route_id, |
| 880 bool swapped_out, | 882 bool swapped_out, |
| 881 bool hidden) { | 883 bool hidden) { |
| 882 CHECK(instance); | 884 CHECK(instance); |
| 883 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. | 885 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. |
| 884 | 886 |
| 887 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | |
| 888 int routing_id = MSG_ROUTING_NONE; | |
| 889 | |
| 885 // We are creating a pending or swapped out RFH here. We should never create | 890 // We are creating a pending or swapped out RFH here. We should never create |
| 886 // it in the same SiteInstance as our current RFH. | 891 // it in the same SiteInstance as our current RFH. |
| 887 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 892 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 888 | 893 |
| 889 // Check if we've already created an RFH for this SiteInstance. If so, try | 894 // Check if we've already created an RFH for this SiteInstance. If so, try |
| 890 // to re-use the existing one, which has already been initialized. We'll | 895 // to re-use the existing one, which has already been initialized. We'll |
| 891 // remove it from the list of swapped out hosts if it commits. | 896 // remove it from the list of swapped out hosts if it commits. |
| 892 RenderFrameHostImpl* new_render_frame_host = | 897 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 893 GetSwappedOutRenderFrameHost(instance); | |
| 894 | 898 |
| 895 FrameTreeNode* parent_node = NULL; | 899 FrameTreeNode* parent_node = NULL; |
| 896 if (frame_tree_node_) | 900 if (frame_tree_node_) |
| 897 parent_node = frame_tree_node_->parent(); | 901 parent_node = frame_tree_node_->parent(); |
| 898 | 902 |
| 899 if (new_render_frame_host) { | 903 if (proxy) { |
| 904 routing_id = proxy->render_view_host()->GetRoutingID(); | |
| 905 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | |
| 900 // Prevent the process from exiting while we're trying to use it. | 906 // Prevent the process from exiting while we're trying to use it. |
| 901 if (!swapped_out) { | 907 if (!swapped_out) { |
| 908 new_render_frame_host = proxy->PassFrameHost(); | |
| 902 new_render_frame_host->GetProcess()->AddPendingView(); | 909 new_render_frame_host->GetProcess()->AddPendingView(); |
| 910 | |
| 911 proxy_hosts_.erase(instance->GetId()); | |
| 912 delete proxy; | |
| 903 } else { | 913 } else { |
| 904 // Detect if this is a cross-process child frame that is navigating | 914 // Detect if this is a cross-process child frame that is navigating |
| 905 // back to the same SiteInstance as its parent. | 915 // back to the same SiteInstance as its parent. |
| 906 if (parent_node && cross_process_frame_connector_ && | 916 if (parent_node && cross_process_frame_connector_ && |
| 907 render_frame_host_->GetSiteInstance() == parent_node-> | 917 render_frame_host_->GetSiteInstance() == parent_node-> |
| 908 render_manager()->current_frame_host()->GetSiteInstance()) { | 918 render_manager()->current_frame_host()->GetSiteInstance()) { |
| 909 delete cross_process_frame_connector_; | 919 delete cross_process_frame_connector_; |
| 910 cross_process_frame_connector_ = NULL; | 920 cross_process_frame_connector_ = NULL; |
| 911 } | 921 } |
| 912 } | 922 } |
| 913 } else { | 923 } else { |
| 914 // Create a new RenderFrameHost if we don't find an existing one. | 924 // Create a new RenderFrameHost if we don't find an existing one. |
| 915 // TODO(creis): Make new_render_frame_host a scoped_ptr. | 925 new_render_frame_host = CreateRenderFrameHost( |
| 916 new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE, | 926 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); |
| 917 MSG_ROUTING_NONE, swapped_out, | 927 RenderViewHostImpl* render_view_host = |
| 918 hidden); | 928 new_render_frame_host->render_view_host(); |
| 919 | 929 |
| 920 // If the new RFH is swapped out already, store it. Otherwise prevent the | 930 // If the new RFH is swapped out already, store it. Otherwise prevent the |
| 921 // process from exiting while we're trying to navigate in it. | 931 // process from exiting while we're trying to navigate in it. |
| 922 if (swapped_out) { | 932 if (!swapped_out) { |
|
Charlie Reis
2014/04/09 21:48:30
Why reverse this block? I'm not opposed, but we s
nasko
2014/04/10 20:37:36
Done.
| |
| 923 swapped_out_hosts_[instance->GetId()] = new_render_frame_host; | 933 new_render_frame_host->GetProcess()->AddPendingView(); |
| 924 } else { | 934 } else { |
| 925 new_render_frame_host->GetProcess()->AddPendingView(); | 935 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost( |
| 936 new_render_frame_host.Pass()); | |
| 926 } | 937 } |
| 927 | 938 |
| 928 RenderViewHostImpl* render_view_host = | |
| 929 new_render_frame_host->render_view_host(); | |
| 930 bool success = InitRenderView(render_view_host, opener_route_id); | 939 bool success = InitRenderView(render_view_host, opener_route_id); |
| 931 if (success && frame_tree_node_->IsMainFrame()) { | 940 if (success && frame_tree_node_->IsMainFrame()) { |
| 932 // Don't show the main frame's view until we get a DidNavigate from it. | 941 // Don't show the main frame's view until we get a DidNavigate from it. |
| 933 render_view_host->GetView()->Hide(); | 942 render_view_host->GetView()->Hide(); |
| 934 } else if (!swapped_out && pending_render_frame_host_) { | 943 } else if (!swapped_out && pending_render_frame_host_) { |
| 935 CancelPending(); | 944 CancelPending(); |
| 936 } | 945 } |
| 946 routing_id = render_view_host->GetRoutingID(); | |
| 937 } | 947 } |
| 938 | 948 |
| 939 // Use this as our new pending RFH if it isn't swapped out. | 949 // Use this as our new pending RFH if it isn't swapped out. |
| 940 if (!swapped_out) | 950 if (!swapped_out) |
| 941 pending_render_frame_host_.reset(new_render_frame_host); | 951 pending_render_frame_host_ = new_render_frame_host.Pass(); |
| 942 | 952 |
| 943 return new_render_frame_host->render_view_host()->GetRoutingID(); | 953 return routing_id; |
| 944 } | 954 } |
| 945 | 955 |
| 946 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, | 956 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, |
| 947 int opener_route_id) { | 957 int opener_route_id) { |
| 948 // We may have initialized this RenderViewHost for another RenderFrameHost. | 958 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 949 if (render_view_host->IsRenderViewLive()) | 959 if (render_view_host->IsRenderViewLive()) |
| 950 return true; | 960 return true; |
| 951 | 961 |
| 952 // If the pending navigation is to a WebUI and the RenderView is not in a | 962 // If the pending navigation is to a WebUI and the RenderView is not in a |
| 953 // guest process, tell the RenderViewHost about any bindings it will need | 963 // guest process, tell the RenderViewHost about any bindings it will need |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1010 bool focus_render_view = !will_focus_location_bar && | 1020 bool focus_render_view = !will_focus_location_bar && |
| 1011 render_frame_host_->render_view_host()->GetView() && | 1021 render_frame_host_->render_view_host()->GetView() && |
| 1012 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1022 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
| 1013 | 1023 |
| 1014 // TODO(creis): As long as show/hide are on RVH, we don't want to do them for | 1024 // TODO(creis): As long as show/hide are on RVH, we don't want to do them for |
| 1015 // subframe navigations or they'll interfere with the top-level page. | 1025 // subframe navigations or they'll interfere with the top-level page. |
| 1016 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1026 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 1017 | 1027 |
| 1018 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1028 // Swap in the pending frame and make it active. Also ensure the FrameTree |
| 1019 // stays in sync. | 1029 // stays in sync. |
| 1020 RenderFrameHostImpl* old_render_frame_host = render_frame_host_.release(); | 1030 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 1031 render_frame_host_.Pass(); | |
| 1021 render_frame_host_ = pending_render_frame_host_.Pass(); | 1032 render_frame_host_ = pending_render_frame_host_.Pass(); |
| 1022 if (is_main_frame) | 1033 if (is_main_frame) |
| 1023 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1034 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 1024 | 1035 |
| 1025 // The process will no longer try to exit, so we can decrement the count. | 1036 // The process will no longer try to exit, so we can decrement the count. |
| 1026 render_frame_host_->GetProcess()->RemovePendingView(); | 1037 render_frame_host_->GetProcess()->RemovePendingView(); |
| 1027 | 1038 |
| 1028 // If the view is gone, then this RenderViewHost died while it was hidden. | 1039 // If the view is gone, then this RenderViewHost died while it was hidden. |
| 1029 // We ignored the RenderProcessGone call at the time, so we should send it now | 1040 // We ignored the RenderProcessGone call at the time, so we should send it now |
| 1030 // to make sure the sad tab shows up, etc. | 1041 // to make sure the sad tab shows up, etc. |
| 1031 if (!render_frame_host_->render_view_host()->GetView()) { | 1042 if (!render_frame_host_->render_view_host()->GetView()) { |
| 1032 delegate_->RenderProcessGoneFromRenderManager( | 1043 delegate_->RenderProcessGoneFromRenderManager( |
| 1033 render_frame_host_->render_view_host()); | 1044 render_frame_host_->render_view_host()); |
| 1034 } else if (!delegate_->IsHidden()) { | 1045 } else if (!delegate_->IsHidden()) { |
| 1035 render_frame_host_->render_view_host()->GetView()->Show(); | 1046 render_frame_host_->render_view_host()->GetView()->Show(); |
| 1036 } | 1047 } |
| 1037 | 1048 |
| 1038 // If the old view is live and top-level, hide it now that the new one is | 1049 // If the old view is live and top-level, hide it now that the new one is |
| 1039 // visible. | 1050 // visible. |
| 1040 int32 old_site_instance_id = | 1051 int32 old_site_instance_id = |
| 1041 old_render_frame_host->GetSiteInstance()->GetId(); | 1052 old_render_frame_host->GetSiteInstance()->GetId(); |
| 1042 if (old_render_frame_host->render_view_host()->GetView()) { | 1053 if (old_render_frame_host->render_view_host()->GetView()) { |
| 1043 if (is_main_frame) { | 1054 if (is_main_frame) { |
| 1044 old_render_frame_host->render_view_host()->GetView()->Hide(); | 1055 old_render_frame_host->render_view_host()->GetView()->Hide(); |
| 1045 old_render_frame_host->render_view_host()->WasSwappedOut(base::Bind( | 1056 old_render_frame_host->render_view_host()->WasSwappedOut(base::Bind( |
| 1046 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | 1057 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, |
| 1047 weak_factory_.GetWeakPtr(), | 1058 weak_factory_.GetWeakPtr(), |
| 1048 old_site_instance_id, | 1059 old_site_instance_id, |
| 1049 old_render_frame_host)); | 1060 old_render_frame_host.get())); |
| 1050 } else { | |
| 1051 // TODO(creis): We'll need to set this back to false if we navigate back. | |
| 1052 old_render_frame_host->set_swapped_out(true); | |
| 1053 } | 1061 } |
| 1062 // TODO(creis): We'll need to set this back to false if we navigate back. | |
| 1063 old_render_frame_host->set_swapped_out(true); | |
|
Charlie Reis
2014/04/09 21:48:30
I don't think we want to do this for main frames,
nasko
2014/04/10 20:37:36
Done.
| |
| 1054 } | 1064 } |
| 1055 | 1065 |
| 1056 // Make sure the size is up to date. (Fix for bug 1079768.) | 1066 // Make sure the size is up to date. (Fix for bug 1079768.) |
| 1057 delegate_->UpdateRenderViewSizeForRenderManager(); | 1067 delegate_->UpdateRenderViewSizeForRenderManager(); |
| 1058 | 1068 |
| 1059 if (will_focus_location_bar) { | 1069 if (will_focus_location_bar) { |
| 1060 delegate_->SetFocusToLocationBar(false); | 1070 delegate_->SetFocusToLocationBar(false); |
| 1061 } else if (focus_render_view && | 1071 } else if (focus_render_view && |
| 1062 render_frame_host_->render_view_host()->GetView()) { | 1072 render_frame_host_->render_view_host()->GetView()) { |
| 1063 RenderWidgetHostViewPort::FromRWHV( | 1073 RenderWidgetHostViewPort::FromRWHV( |
| 1064 render_frame_host_->render_view_host()->GetView())->Focus(); | 1074 render_frame_host_->render_view_host()->GetView())->Focus(); |
| 1065 } | 1075 } |
| 1066 | 1076 |
| 1067 // Notify that we've swapped RenderFrameHosts. We do this before shutting down | 1077 // Notify that we've swapped RenderFrameHosts. We do this before shutting down |
| 1068 // the RFH so that we can clean up RendererResources related to the RFH first. | 1078 // the RFH so that we can clean up RendererResources related to the RFH first. |
| 1069 // TODO(creis): Only do this on top-level RFHs for now, and later update it to | 1079 // TODO(creis): Only do this on top-level RFHs for now, and later update it to |
| 1070 // pass the RFHs. | 1080 // pass the RFHs. |
| 1071 if (is_main_frame) { | 1081 if (is_main_frame) { |
| 1072 delegate_->NotifySwappedFromRenderManager( | 1082 delegate_->NotifySwappedFromRenderManager( |
| 1073 old_render_frame_host->render_view_host(), | 1083 old_render_frame_host->render_view_host(), |
| 1074 render_frame_host_->render_view_host()); | 1084 render_frame_host_->render_view_host()); |
| 1075 } | 1085 } |
| 1076 | 1086 |
| 1077 // If the pending frame was on the swapped out list, we can remove it. | 1087 // If the pending frame was on the swapped out list, we can remove it. |
|
Charlie Reis
2014/04/09 21:48:30
This suggests that the pending can still be on the
nasko
2014/04/10 20:37:36
Done.
| |
| 1078 swapped_out_hosts_.erase(render_frame_host_->GetSiteInstance()->GetId()); | 1088 proxy_hosts_.erase(render_frame_host_->GetSiteInstance()->GetId()); |
| 1079 | 1089 |
| 1080 if (old_render_frame_host->render_view_host()->IsRenderViewLive()) { | 1090 if (old_render_frame_host->render_view_host()->IsRenderViewLive()) { |
|
Charlie Reis
2014/04/09 21:48:30
One suggestion to make this block of nested ifs sl
nasko
2014/04/10 20:37:36
Done.
| |
| 1081 // If the old RFH is live, we are swapping it out and should keep track of | 1091 // If the old RFH is live, we are swapping it out and should keep track of |
| 1082 // it in case we navigate back to it, or it is waiting for the unload event | 1092 // it in case we navigate back to it, or it is waiting for the unload event |
| 1083 // to execute in the background. | 1093 // to execute in the background. |
| 1084 // TODO(creis): Swap out the subframe in --site-per-process. | 1094 // TODO(creis): Swap out the subframe in --site-per-process. |
| 1085 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 1095 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) |
| 1086 DCHECK(old_render_frame_host->is_swapped_out() || | 1096 DCHECK(old_render_frame_host->is_swapped_out() || |
| 1087 !RenderViewHostImpl::IsRVHStateActive( | 1097 !RenderViewHostImpl::IsRVHStateActive( |
| 1088 old_render_frame_host->render_view_host()->rvh_state())); | 1098 old_render_frame_host->render_view_host()->rvh_state())); |
| 1089 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make | 1099 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make |
| 1090 // sure we don't get different rvh instances for the same site instance | 1100 // sure we don't get different rvh instances for the same site instance |
| 1091 // in the same rvhmgr. | 1101 // in the same rvhmgr. |
| 1092 // TODO(creis): Clean this up. | 1102 // TODO(creis): Clean this up. |
| 1093 RenderFrameHostMap::iterator iter = | 1103 RenderFrameHostMap::iterator iter = proxy_hosts_.find(old_site_instance_id); |
| 1094 swapped_out_hosts_.find(old_site_instance_id); | 1104 if (iter != proxy_hosts_.end() && |
| 1095 if (iter != swapped_out_hosts_.end() && | 1105 iter->second->render_frame_host() != old_render_frame_host) { |
| 1096 iter->second != old_render_frame_host) { | 1106 // Delete the proxy that will be replaced in the map to avoid a leak. |
| 1097 // Delete the RFH that will be replaced in the map to avoid a leak. | |
| 1098 delete iter->second; | 1107 delete iter->second; |
| 1099 } | 1108 } |
| 1109 | |
| 1110 SiteInstanceImpl* old_site_instance = static_cast<SiteInstanceImpl*>( | |
|
Charlie Reis
2014/04/09 21:48:30
This makes me nervous. Deleting old_render_frame_
nasko
2014/04/10 20:37:36
Done.
| |
| 1111 old_render_frame_host->GetSiteInstance()); | |
| 1112 | |
| 1100 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, | 1113 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, |
| 1101 // the RenderFrameHost should be put in the map of RenderFrameHosts pending | 1114 // the RenderFrameHost should be put in the map of RenderFrameHosts pending |
| 1102 // shutdown. Otherwise, it is stored in the map of swapped out | 1115 // shutdown. Otherwise, it is stored in the map of proxy hosts. |
| 1103 // RenderFrameHosts. | |
| 1104 if (old_render_frame_host->render_view_host()->rvh_state() == | 1116 if (old_render_frame_host->render_view_host()->rvh_state() == |
| 1105 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { | 1117 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { |
| 1106 swapped_out_hosts_.erase(old_site_instance_id); | 1118 proxy_hosts_.erase(old_site_instance_id); |
| 1107 RFHPendingDeleteMap::iterator pending_delete_iter = | 1119 RFHPendingDeleteMap::iterator pending_delete_iter = |
| 1108 pending_delete_hosts_.find(old_site_instance_id); | 1120 pending_delete_hosts_.find(old_site_instance_id); |
| 1109 if (pending_delete_iter == pending_delete_hosts_.end() || | 1121 if (pending_delete_iter == pending_delete_hosts_.end() || |
| 1110 pending_delete_iter->second.get() != old_render_frame_host) { | 1122 pending_delete_iter->second.get() != old_render_frame_host) { |
| 1111 pending_delete_hosts_[old_site_instance_id] = | 1123 pending_delete_hosts_[old_site_instance_id] = |
| 1112 linked_ptr<RenderFrameHostImpl>(old_render_frame_host); | 1124 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); |
| 1113 } | 1125 } |
| 1114 } else { | 1126 } else { |
| 1115 swapped_out_hosts_[old_site_instance_id] = old_render_frame_host; | 1127 // If there are no active views in this SiteInstance, it means that |
| 1116 } | 1128 // this RFH was the last active one in the SiteInstance. Now that we |
| 1117 | 1129 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
| 1118 // If there are no active views in this SiteInstance, it means that | 1130 // in this SiteInstance. We do this after ensuring the RFH is on the |
| 1119 // this RFH was the last active one in the SiteInstance. Now that we | 1131 // swapped out list to simplify the deletion. |
|
Charlie Reis
2014/04/09 21:48:30
I'm having trouble wrapping my head around this ch
nasko
2014/04/10 20:37:36
As we discussed, I've moved it around to preserve
| |
| 1120 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs | 1132 if (!old_site_instance->active_view_count()) { |
| 1121 // in this SiteInstance. We do this after ensuring the RFH is on the | 1133 old_render_frame_host.reset(NULL); |
| 1122 // swapped out list to simplify the deletion. | 1134 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
| 1123 if (!static_cast<SiteInstanceImpl*>( | 1135 } else { |
| 1124 old_render_frame_host->GetSiteInstance())->active_view_count()) { | 1136 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost( |
| 1125 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1137 old_render_frame_host.Pass()); |
| 1126 // This is deleted while cleaning up the SiteInstance's views. | 1138 } |
| 1127 old_render_frame_host = NULL; | |
| 1128 } | 1139 } |
| 1129 } else { | 1140 } else { |
| 1130 delete old_render_frame_host; | 1141 old_render_frame_host.reset(NULL); |
|
Charlie Reis
2014/04/09 21:48:30
The default argument is NULL, so you can just say
nasko
2014/04/10 20:37:36
Done.
| |
| 1131 } | 1142 } |
| 1132 } | 1143 } |
| 1133 | 1144 |
| 1134 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1145 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
| 1135 int32 site_instance_id) { | 1146 int32 site_instance_id) { |
| 1136 // First remove any swapped out RFH for this SiteInstance from our own list. | 1147 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1137 ClearSwappedOutRFHsInSiteInstance(site_instance_id, frame_tree_node_); | 1148 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1138 | 1149 |
| 1139 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1150 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
| 1140 // in the SiteInstance, then tell their respective FrameTrees to remove all | 1151 // in the SiteInstance, then tell their respective FrameTrees to remove all |
| 1141 // swapped out RenderFrameHosts corresponding to them. | 1152 // RenderFrameProxyHosts corresponding to them. |
| 1142 // TODO(creis): Replace this with a RenderFrameHostIterator that protects | 1153 // TODO(creis): Replace this with a RenderFrameHostIterator that protects |
| 1143 // against use-after-frees if a later element is deleted before getting to it. | 1154 // against use-after-frees if a later element is deleted before getting to it. |
| 1144 scoped_ptr<RenderWidgetHostIterator> widgets( | 1155 scoped_ptr<RenderWidgetHostIterator> widgets( |
| 1145 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); | 1156 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); |
| 1146 while (RenderWidgetHost* widget = widgets->GetNextHost()) { | 1157 while (RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 1147 if (!widget->IsRenderView()) | 1158 if (!widget->IsRenderView()) |
| 1148 continue; | 1159 continue; |
| 1149 RenderViewHostImpl* rvh = | 1160 RenderViewHostImpl* rvh = |
| 1150 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); | 1161 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); |
| 1151 if (site_instance_id == rvh->GetSiteInstance()->GetId()) { | 1162 if (site_instance_id == rvh->GetSiteInstance()->GetId()) { |
| 1152 // This deletes all RenderFrameHosts using the |rvh|, which then causes | 1163 // This deletes all RenderFrameHosts using the |rvh|, which then causes |
| 1153 // |rvh| to Shutdown. | 1164 // |rvh| to Shutdown. |
| 1154 FrameTree* tree = rvh->GetDelegate()->GetFrameTree(); | 1165 FrameTree* tree = rvh->GetDelegate()->GetFrameTree(); |
| 1155 tree->ForEach(base::Bind( | 1166 tree->ForEach(base::Bind( |
| 1156 &RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance, | 1167 &RenderFrameHostManager::ClearProxiesInSiteInstance, |
| 1157 site_instance_id)); | 1168 site_instance_id)); |
| 1158 } | 1169 } |
| 1159 } | 1170 } |
| 1160 } | 1171 } |
| 1161 | 1172 |
| 1162 RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate( | 1173 RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate( |
| 1163 const NavigationEntryImpl& entry) { | 1174 const NavigationEntryImpl& entry) { |
| 1164 // If we are currently navigating cross-process, we want to get back to normal | 1175 // If we are currently navigating cross-process, we want to get back to normal |
| 1165 // and then navigate as usual. | 1176 // and then navigate as usual. |
| 1166 if (cross_navigation_pending_) { | 1177 if (cross_navigation_pending_) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1324 RenderFrameHostImpl* pending_render_frame_host = | 1335 RenderFrameHostImpl* pending_render_frame_host = |
| 1325 pending_render_frame_host_.release(); | 1336 pending_render_frame_host_.release(); |
| 1326 | 1337 |
| 1327 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( | 1338 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( |
| 1328 pending_render_frame_host->render_view_host(), | 1339 pending_render_frame_host->render_view_host(), |
| 1329 render_frame_host_->render_view_host()); | 1340 render_frame_host_->render_view_host()); |
| 1330 | 1341 |
| 1331 // We no longer need to prevent the process from exiting. | 1342 // We no longer need to prevent the process from exiting. |
| 1332 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1343 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 1333 | 1344 |
| 1334 // The pending RFH may already be on the swapped out list if we started to | 1345 // If the SiteInstance for the pending RFH is being used by others, don't |
| 1335 // swap it back in and then canceled. If so, make sure it gets swapped out | 1346 // delete the RFH, just swap it out and it can be reused at a later point. |
| 1336 // again. If it's not on the swapped out list (e.g., aborting a pending | 1347 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( |
| 1337 // load), then it's safe to shut down. | 1348 pending_render_frame_host->GetSiteInstance()); |
| 1338 if (IsOnSwappedOutList(pending_render_frame_host)) { | 1349 if (!site_instance->active_view_count()) { |
|
Charlie Reis
2014/04/09 21:48:30
Isn't this backwards? If the view count is 0, we
nasko
2014/04/10 20:37:36
Done.
| |
| 1339 // Any currently suspended navigations are no longer needed. | 1350 // Any currently suspended navigations are no longer needed. |
| 1340 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1351 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
| 1341 | 1352 |
| 1342 pending_render_frame_host->SwapOut(); | 1353 pending_render_frame_host->SwapOut(); |
| 1343 } else { | 1354 } else { |
| 1344 // We won't be coming back, so shut this one down. | 1355 // We won't be coming back, so shut this one down. |
| 1345 delete pending_render_frame_host; | 1356 delete pending_render_frame_host; |
| 1346 } | 1357 } |
| 1347 | 1358 |
| 1348 pending_web_ui_.reset(); | 1359 pending_web_ui_.reset(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1362 NOTREACHED(); | 1373 NOTREACHED(); |
| 1363 pending_render_frame_host_.reset(); | 1374 pending_render_frame_host_.reset(); |
| 1364 } | 1375 } |
| 1365 | 1376 |
| 1366 // Make sure deleted RVHs are not kept in the swapped out list while we are | 1377 // Make sure deleted RVHs are not kept in the swapped out list while we are |
| 1367 // still alive. (If render_frame_host_ is null, we're already being deleted.) | 1378 // still alive. (If render_frame_host_ is null, we're already being deleted.) |
| 1368 if (!render_frame_host_) | 1379 if (!render_frame_host_) |
| 1369 return; | 1380 return; |
| 1370 | 1381 |
| 1371 // We can't look it up by SiteInstance ID, which may no longer be valid. | 1382 // We can't look it up by SiteInstance ID, which may no longer be valid. |
| 1372 for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin(); | 1383 for (RenderFrameHostMap::iterator iter = proxy_hosts_.begin(); |
| 1373 iter != swapped_out_hosts_.end(); | 1384 iter != proxy_hosts_.end(); |
| 1374 ++iter) { | 1385 ++iter) { |
| 1375 if (iter->second->render_view_host() == rvh) { | 1386 if (iter->second->render_view_host() == rvh) { |
| 1376 swapped_out_hosts_.erase(iter); | 1387 proxy_hosts_.erase(iter); |
| 1377 break; | 1388 break; |
| 1378 } | 1389 } |
| 1379 } | 1390 } |
| 1380 } | 1391 } |
| 1381 | 1392 |
| 1382 bool RenderFrameHostManager::IsRVHOnSwappedOutList( | 1393 bool RenderFrameHostManager::IsRVHOnSwappedOutList( |
| 1383 RenderViewHostImpl* rvh) const { | 1394 RenderViewHostImpl* rvh) const { |
| 1384 RenderFrameHostImpl* render_frame_host = GetSwappedOutRenderFrameHost( | 1395 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost( |
| 1385 rvh->GetSiteInstance()); | 1396 rvh->GetSiteInstance()); |
| 1386 if (!render_frame_host) | 1397 if (!proxy) |
| 1387 return false; | 1398 return false; |
| 1388 return IsOnSwappedOutList(render_frame_host); | 1399 return IsOnSwappedOutList(proxy->render_frame_host()); |
| 1389 } | 1400 } |
| 1390 | 1401 |
| 1391 bool RenderFrameHostManager::IsOnSwappedOutList( | 1402 bool RenderFrameHostManager::IsOnSwappedOutList( |
| 1392 RenderFrameHostImpl* rfh) const { | 1403 RenderFrameHostImpl* rfh) const { |
| 1393 if (!rfh->GetSiteInstance()) | 1404 if (!rfh->GetSiteInstance()) |
| 1394 return false; | 1405 return false; |
| 1395 | 1406 |
| 1396 RenderFrameHostMap::const_iterator iter = swapped_out_hosts_.find( | 1407 RenderFrameHostMap::const_iterator iter = proxy_hosts_.find( |
| 1397 rfh->GetSiteInstance()->GetId()); | 1408 rfh->GetSiteInstance()->GetId()); |
| 1398 if (iter == swapped_out_hosts_.end()) | 1409 if (iter == proxy_hosts_.end()) |
| 1399 return false; | 1410 return false; |
| 1400 | 1411 |
| 1401 return iter->second == rfh; | 1412 return iter->second->render_frame_host() == rfh; |
| 1402 } | 1413 } |
| 1403 | 1414 |
| 1404 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( | 1415 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( |
| 1405 SiteInstance* instance) const { | 1416 SiteInstance* instance) const { |
| 1406 RenderFrameHostImpl* render_frame_host = | 1417 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1407 GetSwappedOutRenderFrameHost(instance); | 1418 if (proxy) |
| 1408 if (render_frame_host) | 1419 return proxy->render_view_host(); |
| 1409 return render_frame_host->render_view_host(); | |
| 1410 return NULL; | 1420 return NULL; |
| 1411 } | 1421 } |
| 1412 | 1422 |
| 1413 RenderFrameHostImpl* RenderFrameHostManager::GetSwappedOutRenderFrameHost( | 1423 RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost( |
| 1414 SiteInstance* instance) const { | 1424 SiteInstance* instance) const { |
| 1415 RenderFrameHostMap::const_iterator iter = | 1425 RenderFrameHostMap::const_iterator iter = |
| 1416 swapped_out_hosts_.find(instance->GetId()); | 1426 proxy_hosts_.find(instance->GetId()); |
| 1417 if (iter != swapped_out_hosts_.end()) | 1427 if (iter != proxy_hosts_.end()) |
| 1418 return iter->second; | 1428 return iter->second; |
| 1419 | 1429 |
| 1420 return NULL; | 1430 return NULL; |
| 1421 } | 1431 } |
| 1422 | 1432 |
| 1423 } // namespace content | 1433 } // namespace content |
| OLD | NEW |