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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <string> | 10 #include <string> |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 // Doing this is important in the case where the replacement proxy is created | 692 // Doing this is important in the case where the replacement proxy is created |
693 // above, as the RenderViewHost will continue to exist and should be | 693 // above, as the RenderViewHost will continue to exist and should be |
694 // considered swapped out if it is ever reused. When there's no replacement | 694 // considered swapped out if it is ever reused. When there's no replacement |
695 // proxy, this doesn't really matter, as the RenderViewHost will be destroyed | 695 // proxy, this doesn't really matter, as the RenderViewHost will be destroyed |
696 // shortly, since |render_frame_host| is its last active frame and will be | 696 // shortly, since |render_frame_host| is its last active frame and will be |
697 // deleted below. See https://crbug.com/627400. | 697 // deleted below. See https://crbug.com/627400. |
698 if (frame_tree_node_->IsMainFrame()) { | 698 if (frame_tree_node_->IsMainFrame()) { |
699 rvh->set_main_frame_routing_id(MSG_ROUTING_NONE); | 699 rvh->set_main_frame_routing_id(MSG_ROUTING_NONE); |
700 rvh->set_is_active(false); | 700 rvh->set_is_active(false); |
701 rvh->set_is_swapped_out(true); | 701 rvh->set_is_swapped_out(true); |
702 | |
703 if (rvh->GetWidget()->GetView()) { | |
704 rvh->GetWidget()->GetView()->Destroy(); | |
705 rvh->GetWidget()->SetView(nullptr); | |
706 } | |
702 } | 707 } |
703 | 708 |
704 render_frame_host.reset(); | 709 render_frame_host.reset(); |
705 | 710 |
706 // If a new RenderFrameProxyHost was created above, or if the old proxy isn't | 711 // If a new RenderFrameProxyHost was created above, or if the old proxy isn't |
707 // live, create the RenderFrameProxy in the renderer, so that other frames | 712 // live, create the RenderFrameProxy in the renderer, so that other frames |
708 // can still communicate with this frame. See https://crbug.com/653746. | 713 // can still communicate with this frame. See https://crbug.com/653746. |
709 if (proxy && !proxy->is_render_frame_proxy_live()) | 714 if (proxy && !proxy->is_render_frame_proxy_live()) |
710 proxy->InitRenderFrameProxy(); | 715 proxy->InitRenderFrameProxy(); |
711 } | 716 } |
712 | 717 |
713 bool RenderFrameHostManager::DeleteFromPendingList( | 718 bool RenderFrameHostManager::DeleteFromPendingList( |
714 RenderFrameHostImpl* render_frame_host) { | 719 RenderFrameHostImpl* render_frame_host) { |
720 // If this is a main frame RFH that's about to be deleted, update its RVH's | |
721 // swapped-out state here. https://crbug.com/505887 | |
722 if (frame_tree_node_->IsMainFrame()) { | |
723 RenderViewHostImpl* rvh = render_frame_host->render_view_host(); | |
724 | |
725 rvh->set_is_active(false); | |
lfg
2016/11/29 17:41:22
I had to change this back from the DCHECK, since t
Charlie Reis
2016/11/29 19:35:55
Ok. Please mention that in a comment.
alexmos
2016/11/29 19:47:37
I'm a bit confused by this actually. We start the
| |
726 rvh->set_is_swapped_out(true); | |
727 } | |
728 | |
715 for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin(); | 729 for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin(); |
716 iter != pending_delete_hosts_.end(); | 730 iter != pending_delete_hosts_.end(); |
717 iter++) { | 731 iter++) { |
718 if (iter->get() == render_frame_host) { | 732 if (iter->get() == render_frame_host) { |
719 pending_delete_hosts_.erase(iter); | 733 pending_delete_hosts_.erase(iter); |
720 return true; | 734 return true; |
721 } | 735 } |
722 } | 736 } |
723 return false; | 737 return false; |
724 } | 738 } |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1751 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, hidden, | 1765 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, hidden, |
1752 false); | 1766 false); |
1753 RenderViewHostImpl* render_view_host = | 1767 RenderViewHostImpl* render_view_host = |
1754 new_render_frame_host->render_view_host(); | 1768 new_render_frame_host->render_view_host(); |
1755 | 1769 |
1756 // Prevent the process from exiting while we're trying to navigate in it. | 1770 // Prevent the process from exiting while we're trying to navigate in it. |
1757 new_render_frame_host->GetProcess()->AddPendingView(); | 1771 new_render_frame_host->GetProcess()->AddPendingView(); |
1758 | 1772 |
1759 if (frame_tree_node_->IsMainFrame()) { | 1773 if (frame_tree_node_->IsMainFrame()) { |
1760 success = InitRenderView(render_view_host, proxy); | 1774 success = InitRenderView(render_view_host, proxy); |
1761 | |
1762 // If we are reusing the RenderViewHost and it doesn't already have a | |
1763 // RenderWidgetHostView, we need to create one if this is the main frame. | |
1764 if (!render_view_host->GetWidget()->GetView()) | |
1765 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host); | |
1766 } else { | 1775 } else { |
1767 DCHECK(render_view_host->IsRenderViewLive()); | 1776 DCHECK(render_view_host->IsRenderViewLive()); |
1768 } | 1777 } |
1769 | 1778 |
1770 if (success) { | 1779 if (success) { |
1771 if (frame_tree_node_->IsMainFrame()) { | 1780 if (frame_tree_node_->IsMainFrame()) { |
1772 // Don't show the main frame's view until we get a DidNavigate from it. | 1781 // Don't show the main frame's view until we get a DidNavigate from it. |
1773 // Only the RenderViewHost for the top-level RenderFrameHost has a | 1782 // Only the RenderViewHost for the top-level RenderFrameHost has a |
1774 // RenderWidgetHostView; RenderWidgetHosts for out-of-process iframes | 1783 // RenderWidgetHostView; RenderWidgetHosts for out-of-process iframes |
1775 // will be created later and hidden. | 1784 // will be created later and hidden. |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2156 } else { | 2165 } else { |
2157 // PlzNavigate | 2166 // PlzNavigate |
2158 DCHECK(speculative_render_frame_host_); | 2167 DCHECK(speculative_render_frame_host_); |
2159 old_render_frame_host = | 2168 old_render_frame_host = |
2160 SetRenderFrameHost(std::move(speculative_render_frame_host_)); | 2169 SetRenderFrameHost(std::move(speculative_render_frame_host_)); |
2161 } | 2170 } |
2162 | 2171 |
2163 // The process will no longer try to exit, so we can decrement the count. | 2172 // The process will no longer try to exit, so we can decrement the count. |
2164 render_frame_host_->GetProcess()->RemovePendingView(); | 2173 render_frame_host_->GetProcess()->RemovePendingView(); |
2165 | 2174 |
2175 // The RenderViewHost keeps track of the main RenderFrameHost routing id. | |
2176 // If this is committing a main frame navigation, update it and set the | |
2177 // routing id in the RenderViewHost associated with the old RenderFrameHost | |
2178 // to MSG_ROUTING_NONE. | |
2179 if (is_main_frame) { | |
2180 RenderViewHostImpl* rvh = render_frame_host_->render_view_host(); | |
2181 rvh->set_main_frame_routing_id(render_frame_host_->routing_id()); | |
2182 | |
2183 // If we are reusing the RenderViewHost, we need to create the | |
2184 // RenderWidgetHostView if this is the main frame. | |
2185 if (rvh->IsRenderViewLive() && !rvh->is_active()) | |
2186 delegate_->CreateRenderWidgetHostViewForRenderManager(rvh); | |
2187 | |
2188 // If the RenderViewHost is transitioning from swapped out to active state, | |
2189 // it was reused, so dispatch a RenderViewReady event. For example, this | |
2190 // is necessary to hide the sad tab if one is currently displayed. See | |
2191 // https://crbug.com/591984. | |
2192 // | |
2193 // TODO(alexmos): Remove this and move RenderViewReady consumers to use | |
2194 // the main frame's RenderFrameCreated instead. | |
2195 if (!rvh->is_active()) | |
2196 rvh->PostRenderViewReady(); | |
2197 | |
2198 rvh->set_is_active(true); | |
2199 rvh->set_is_swapped_out(false); | |
2200 | |
2201 // Tell the old RenderViewHost it is no longer active. | |
2202 RenderViewHostImpl* old_rvh = old_render_frame_host->render_view_host(); | |
2203 old_rvh->set_main_frame_routing_id(MSG_ROUTING_NONE); | |
2204 old_rvh->set_is_active(false); | |
2205 | |
2206 // Destroy the old RenderWidgetHostView. | |
2207 if (old_rvh->GetWidget()->GetView()) { | |
2208 old_rvh->GetWidget()->GetView()->Destroy(); | |
2209 old_rvh->GetWidget()->SetView(nullptr); | |
2210 } | |
2211 } | |
2212 | |
2166 // Show the new view (or a sad tab) if necessary. | 2213 // Show the new view (or a sad tab) if necessary. |
2167 bool new_rfh_has_view = !!render_frame_host_->GetView(); | 2214 bool new_rfh_has_view = !!render_frame_host_->GetView(); |
2168 if (!delegate_->IsHidden() && new_rfh_has_view) { | 2215 if (!delegate_->IsHidden() && new_rfh_has_view) { |
2169 // In most cases, we need to show the new view. | 2216 // In most cases, we need to show the new view. |
2170 render_frame_host_->GetView()->Show(); | 2217 render_frame_host_->GetView()->Show(); |
2171 } | 2218 } |
2172 if (!new_rfh_has_view) { | 2219 if (!new_rfh_has_view) { |
2173 // If the view is gone, then this RenderViewHost died while it was hidden. | 2220 // If the view is gone, then this RenderViewHost died while it was hidden. |
2174 // We ignored the RenderProcessGone call at the time, so we should send it | 2221 // We ignored the RenderProcessGone call at the time, so we should send it |
2175 // now to make sure the sad tab shows up, etc. | 2222 // now to make sure the sad tab shows up, etc. |
2176 DCHECK(!render_frame_host_->IsRenderFrameLive()); | 2223 DCHECK(!render_frame_host_->IsRenderFrameLive()); |
2177 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive()); | 2224 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive()); |
2178 render_frame_host_->ResetLoadingState(); | 2225 render_frame_host_->ResetLoadingState(); |
2179 delegate_->RenderProcessGoneFromRenderManager( | 2226 delegate_->RenderProcessGoneFromRenderManager( |
2180 render_frame_host_->render_view_host()); | 2227 render_frame_host_->render_view_host()); |
2181 } | 2228 } |
2182 | 2229 |
2183 // For top-level frames, also hide the old RenderViewHost's view. | |
2184 // TODO(creis): As long as show/hide are on RVH, we don't want to hide on | |
2185 // subframe navigations or we will interfere with the top-level frame. | |
2186 if (is_main_frame && | |
2187 old_render_frame_host->render_view_host()->GetWidget()->GetView()) { | |
2188 old_render_frame_host->render_view_host()->GetWidget()->GetView()->Hide(); | |
2189 } | |
2190 | |
2191 // Make sure the size is up to date. (Fix for bug 1079768.) | 2230 // Make sure the size is up to date. (Fix for bug 1079768.) |
2192 delegate_->UpdateRenderViewSizeForRenderManager(); | 2231 delegate_->UpdateRenderViewSizeForRenderManager(); |
2193 | 2232 |
2194 if (will_focus_location_bar) { | 2233 if (will_focus_location_bar) { |
2195 delegate_->SetFocusToLocationBar(false); | 2234 delegate_->SetFocusToLocationBar(false); |
2196 } else if (focus_render_view && render_frame_host_->GetView()) { | 2235 } else if (focus_render_view && render_frame_host_->GetView()) { |
2197 if (is_main_frame) { | 2236 if (is_main_frame) { |
2198 render_frame_host_->GetView()->Focus(); | 2237 render_frame_host_->GetView()->Focus(); |
2199 } else { | 2238 } else { |
2200 // The main frame's view is already focused, but we need to set | 2239 // The main frame's view is already focused, but we need to set |
2201 // page-level focus in the subframe's renderer. | 2240 // page-level focus in the subframe's renderer. |
2202 frame_tree_node_->frame_tree()->SetPageFocus( | 2241 frame_tree_node_->frame_tree()->SetPageFocus( |
2203 render_frame_host_->GetSiteInstance(), true); | 2242 render_frame_host_->GetSiteInstance(), true); |
2204 } | 2243 } |
2205 } | 2244 } |
2206 | 2245 |
2207 // Notify that we've swapped RenderFrameHosts. We do this before shutting down | 2246 // Notify that we've swapped RenderFrameHosts. We do this before shutting down |
2208 // the RFH so that we can clean up RendererResources related to the RFH first. | 2247 // the RFH so that we can clean up RendererResources related to the RFH first. |
2209 delegate_->NotifySwappedFromRenderManager( | 2248 delegate_->NotifySwappedFromRenderManager( |
2210 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); | 2249 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); |
2211 | 2250 |
2212 // The RenderViewHost keeps track of the main RenderFrameHost routing id. | |
2213 // If this is committing a main frame navigation, update it and set the | |
2214 // routing id in the RenderViewHost associated with the old RenderFrameHost | |
2215 // to MSG_ROUTING_NONE. | |
2216 if (is_main_frame) { | |
2217 RenderViewHostImpl* rvh = render_frame_host_->render_view_host(); | |
2218 rvh->set_main_frame_routing_id(render_frame_host_->routing_id()); | |
2219 | |
2220 // If the RenderViewHost is transitioning from swapped out to active state, | |
2221 // it was reused, so dispatch a RenderViewReady event. For example, this | |
2222 // is necessary to hide the sad tab if one is currently displayed. See | |
2223 // https://crbug.com/591984. | |
2224 // | |
2225 // TODO(alexmos): Remove this and move RenderViewReady consumers to use | |
2226 // the main frame's RenderFrameCreated instead. | |
2227 if (!rvh->is_active()) | |
2228 rvh->PostRenderViewReady(); | |
2229 | |
2230 rvh->set_is_active(true); | |
2231 rvh->set_is_swapped_out(false); | |
2232 old_render_frame_host->render_view_host()->set_main_frame_routing_id( | |
2233 MSG_ROUTING_NONE); | |
2234 } | |
2235 | |
2236 // Swap out the old frame now that the new one is visible. | 2251 // Swap out the old frame now that the new one is visible. |
2237 // This will swap it out and schedule it for deletion when the swap out ack | 2252 // This will swap it out and schedule it for deletion when the swap out ack |
2238 // arrives (or immediately if the process isn't live). | 2253 // arrives (or immediately if the process isn't live). |
2239 SwapOutOldFrame(std::move(old_render_frame_host)); | 2254 SwapOutOldFrame(std::move(old_render_frame_host)); |
2240 | 2255 |
2241 // Since the new RenderFrameHost is now committed, there must be no proxies | 2256 // Since the new RenderFrameHost is now committed, there must be no proxies |
2242 // for its SiteInstance. Delete any existing ones. | 2257 // for its SiteInstance. Delete any existing ones. |
2243 DeleteRenderFrameProxyHost(render_frame_host_->GetSiteInstance()); | 2258 DeleteRenderFrameProxyHost(render_frame_host_->GetSiteInstance()); |
2244 | 2259 |
2245 // If this is a subframe, it should have a CrossProcessFrameConnector | 2260 // If this is a subframe, it should have a CrossProcessFrameConnector |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2735 resolved_url)) { | 2750 resolved_url)) { |
2736 DCHECK(!dest_instance || | 2751 DCHECK(!dest_instance || |
2737 dest_instance == render_frame_host_->GetSiteInstance()); | 2752 dest_instance == render_frame_host_->GetSiteInstance()); |
2738 return false; | 2753 return false; |
2739 } | 2754 } |
2740 | 2755 |
2741 return true; | 2756 return true; |
2742 } | 2757 } |
2743 | 2758 |
2744 } // namespace content | 2759 } // namespace content |
OLD | NEW |