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/logging.h" | 10 #include "base/logging.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 render_frame_delegate_(render_frame_delegate), | 61 render_frame_delegate_(render_frame_delegate), |
| 62 render_view_delegate_(render_view_delegate), | 62 render_view_delegate_(render_view_delegate), |
| 63 render_widget_delegate_(render_widget_delegate), | 63 render_widget_delegate_(render_widget_delegate), |
| 64 interstitial_page_(nullptr), | 64 interstitial_page_(nullptr), |
| 65 should_reuse_web_ui_(false), | 65 should_reuse_web_ui_(false), |
| 66 weak_factory_(this) { | 66 weak_factory_(this) { |
| 67 DCHECK(frame_tree_node_); | 67 DCHECK(frame_tree_node_); |
| 68 } | 68 } |
| 69 | 69 |
| 70 RenderFrameHostManager::~RenderFrameHostManager() { | 70 RenderFrameHostManager::~RenderFrameHostManager() { |
| 71 if (pending_render_frame_host_) | 71 if (pending_render_frame_host_) { |
| 72 UnsetPendingRenderFrameHost(); | 72 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost(); |
| 73 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | |
| 74 } | |
| 73 | 75 |
| 74 if (speculative_render_frame_host_) | 76 if (speculative_render_frame_host_) { |
| 75 UnsetSpeculativeRenderFrameHost(); | 77 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost(); |
| 78 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | |
| 79 } | |
| 76 | 80 |
| 77 if (render_frame_host_ && | 81 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get()); |
| 78 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) { | |
| 79 ShutdownRenderFrameProxyHostsInSiteInstance( | |
| 80 render_frame_host_->GetSiteInstance()->GetId()); | |
| 81 } | |
| 82 | 82 |
| 83 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. | 83 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. |
| 84 // It is important to delete those prior to deleting the current | 84 // It is important to delete those prior to deleting the current |
| 85 // RenderFrameHost, since the CrossProcessFrameConnector (owned by | 85 // RenderFrameHost, since the CrossProcessFrameConnector (owned by |
| 86 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with | 86 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with |
| 87 // the current RenderFrameHost and uses it during its destructor. | 87 // the current RenderFrameHost and uses it during its destructor. |
| 88 STLDeleteValues(&proxy_hosts_); | 88 STLDeleteValues(&proxy_hosts_); |
| 89 | 89 |
| 90 // Release the WebUI prior to resetting the current RenderFrameHost, as the | 90 // Release the WebUI prior to resetting the current RenderFrameHost, as the |
| 91 // WebUI accesses the RenderFrameHost during cleanup. | 91 // WebUI accesses the RenderFrameHost during cleanup. |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 597 // Now close any modal dialogs that would prevent us from swapping out. This | 597 // Now close any modal dialogs that would prevent us from swapping out. This |
| 598 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is | 598 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
| 599 // no longer on the stack when we send the SwapOut message. | 599 // no longer on the stack when we send the SwapOut message. |
| 600 delegate_->CancelModalDialogsForRenderManager(); | 600 delegate_->CancelModalDialogsForRenderManager(); |
| 601 | 601 |
| 602 // If the old RFH is not live, just return as there is no further work to do. | 602 // If the old RFH is not live, just return as there is no further work to do. |
| 603 // It will be deleted and there will be no proxy created. | 603 // It will be deleted and there will be no proxy created. |
| 604 int32 old_site_instance_id = | 604 int32 old_site_instance_id = |
| 605 old_render_frame_host->GetSiteInstance()->GetId(); | 605 old_render_frame_host->GetSiteInstance()->GetId(); |
| 606 if (!old_render_frame_host->IsRenderFrameLive()) { | 606 if (!old_render_frame_host->IsRenderFrameLive()) { |
| 607 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); | 607 ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get()); |
| 608 return; | 608 return; |
| 609 } | 609 } |
| 610 | 610 |
| 611 // If there are no active frames besides this one, we can delete the old | 611 // If there are no active frames besides this one, we can delete the old |
| 612 // RenderFrameHost once it runs its unload handler, without replacing it with | 612 // RenderFrameHost once it runs its unload handler, without replacing it with |
| 613 // a proxy. | 613 // a proxy. |
| 614 size_t active_frame_count = | 614 size_t active_frame_count = |
| 615 old_render_frame_host->GetSiteInstance()->active_frame_count(); | 615 old_render_frame_host->GetSiteInstance()->active_frame_count(); |
| 616 if (active_frame_count <= 1) { | 616 if (active_frame_count <= 1) { |
| 617 // Tell the old RenderFrameHost to swap out, with no proxy to replace it. | 617 // Tell the old RenderFrameHost to swap out, with no proxy to replace it. |
| 618 old_render_frame_host->SwapOut(NULL, true); | 618 old_render_frame_host->SwapOut(NULL, true); |
| 619 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); | 619 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); |
| 620 | 620 |
| 621 // Also clear out any proxies from this SiteInstance, in case this was the | 621 // Also clear out any proxies from this SiteInstance, in case this was the |
| 622 // last one keeping other proxies alive. | 622 // last one keeping other proxies alive. |
| 623 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); | 623 ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get()); |
| 624 | |
| 625 return; | 624 return; |
| 626 } | 625 } |
| 627 | 626 |
| 628 // Otherwise there are active views and we need a proxy for the old RFH. | 627 // Otherwise there are active views and we need a proxy for the old RFH. |
| 629 // (There should not be one yet.) | 628 // (There should not be one yet.) |
| 630 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); | 629 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); |
| 631 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | 630 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
| 632 old_render_frame_host->GetSiteInstance(), frame_tree_node_); | 631 old_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 633 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) | 632 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) |
| 634 << "Inserting a duplicate item."; | 633 << "Inserting a duplicate item."; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 | 675 |
| 677 // Check if the RenderFrameHost is already swapped out, to avoid swapping it | 676 // Check if the RenderFrameHost is already swapped out, to avoid swapping it |
| 678 // out again. | 677 // out again. |
| 679 if (!render_frame_host->is_swapped_out()) | 678 if (!render_frame_host->is_swapped_out()) |
| 680 render_frame_host->SwapOut(proxy, false); | 679 render_frame_host->SwapOut(proxy, false); |
| 681 | 680 |
| 682 if (frame_tree_node_->IsMainFrame()) | 681 if (frame_tree_node_->IsMainFrame()) |
| 683 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | 682 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); |
| 684 } else { | 683 } else { |
| 685 // We won't be coming back, so delete this one. | 684 // We won't be coming back, so delete this one. |
| 685 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host.get()); | |
| 686 render_frame_host.reset(); | 686 render_frame_host.reset(); |
| 687 } | 687 } |
| 688 } | 688 } |
| 689 | 689 |
| 690 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 690 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 691 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 691 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 692 // |render_frame_host| will be deleted when its SwapOut ACK is received, or | 692 // |render_frame_host| will be deleted when its SwapOut ACK is received, or |
| 693 // when the timer times out, or when the RFHM itself is deleted (whichever | 693 // when the timer times out, or when the RFHM itself is deleted (whichever |
| 694 // comes first). | 694 // comes first). |
| 695 pending_delete_hosts_.push_back( | 695 pending_delete_hosts_.push_back( |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1747 if (proxy_to_parent) | 1747 if (proxy_to_parent) |
| 1748 proxy_to_parent->SetChildRWHView(render_frame_host_->GetView()); | 1748 proxy_to_parent->SetChildRWHView(render_frame_host_->GetView()); |
| 1749 } | 1749 } |
| 1750 | 1750 |
| 1751 // After all is done, there must never be a proxy in the list which has the | 1751 // After all is done, there must never be a proxy in the list which has the |
| 1752 // same SiteInstance as the current RenderFrameHost. | 1752 // same SiteInstance as the current RenderFrameHost. |
| 1753 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) == | 1753 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) == |
| 1754 proxy_hosts_.end()); | 1754 proxy_hosts_.end()); |
| 1755 } | 1755 } |
| 1756 | 1756 |
| 1757 void RenderFrameHostManager::ShutdownRenderFrameProxyHostsInSiteInstance( | 1757 void RenderFrameHostManager::ShutdownProxiesIfLastActiveFrameInSiteInstance( |
| 1758 int32 site_instance_id) { | 1758 RenderFrameHostImpl* render_frame_host) { |
| 1759 if (!render_frame_host) | |
| 1760 return; | |
| 1761 if (!RenderFrameHostImpl::IsRFHStateActive(render_frame_host->rfh_state())) | |
| 1762 return; | |
| 1763 if (render_frame_host->GetSiteInstance()->active_frame_count() > 1U) | |
| 1764 return; | |
| 1765 | |
| 1766 // After |render_frame_host| goes away, there will be no active frames left in | |
| 1767 // its SiteInstance, so we can delete all proxies created in that SiteInstance | |
| 1768 // on behalf of frames anywhere in the browsing instance. | |
|
Charlie Reis
2015/04/03 19:55:08
nit: s/browsing instance/BrowsingInstance/
ncarter (slow)
2015/04/03 22:03:33
Done.
| |
| 1769 int32 site_instance_id = render_frame_host->GetSiteInstance()->GetId(); | |
| 1770 | |
| 1759 // First remove any swapped out RFH for this SiteInstance from our own list. | 1771 // First remove any swapped out RFH for this SiteInstance from our own list. |
|
alexmos
2015/04/03 20:55:55
While we're here, does this comment need an update
ncarter (slow)
2015/04/03 22:03:33
Done.
But honestly the comment is the least goofy
Charlie Reis
2015/04/06 16:35:33
Agreed. You'd mentioned that it might be worth tr
| |
| 1760 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1772 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1761 | 1773 |
| 1762 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1774 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
| 1763 // in the SiteInstance, then tell their respective FrameTrees to remove all | 1775 // in the SiteInstance, then tell their respective FrameTrees to remove all |
| 1764 // RenderFrameProxyHosts corresponding to them. | 1776 // RenderFrameProxyHosts corresponding to them. |
| 1765 // TODO(creis): Replace this with a RenderFrameHostIterator that protects | 1777 // TODO(creis): Replace this with a RenderFrameHostIterator that protects |
| 1766 // against use-after-frees if a later element is deleted before getting to it. | 1778 // against use-after-frees if a later element is deleted before getting to it. |
| 1767 scoped_ptr<RenderWidgetHostIterator> widgets( | 1779 scoped_ptr<RenderWidgetHostIterator> widgets( |
| 1768 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); | 1780 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); |
| 1769 while (RenderWidgetHost* widget = widgets->GetNextHost()) { | 1781 while (RenderWidgetHost* widget = widgets->GetNextHost()) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2019 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 2031 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 2020 SiteInstance* instance) { | 2032 SiteInstance* instance) { |
| 2021 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 2033 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 2022 if (iter != proxy_hosts_.end()) { | 2034 if (iter != proxy_hosts_.end()) { |
| 2023 delete iter->second; | 2035 delete iter->second; |
| 2024 proxy_hosts_.erase(iter); | 2036 proxy_hosts_.erase(iter); |
| 2025 } | 2037 } |
| 2026 } | 2038 } |
| 2027 | 2039 |
| 2028 } // namespace content | 2040 } // namespace content |
| OLD | NEW |