| 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 DCHECK(!rvh->is_active()); |
| 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 |