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 // First remove any swapped out RFH for this SiteInstance from our own list. | 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 BrowsingInstance. |
| 1769 int32 site_instance_id = render_frame_host->GetSiteInstance()->GetId(); |
| 1770 |
| 1771 // First remove any proxies for this SiteInstance from our own list. |
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 |