Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 2496233003: Destroy the old RenderWidgetHostView when swapping out a main frame. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <utility> 10 #include <utility>
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // Doing this is important in the case where the replacement proxy is created 687 // Doing this is important in the case where the replacement proxy is created
688 // above, as the RenderViewHost will continue to exist and should be 688 // above, as the RenderViewHost will continue to exist and should be
689 // considered swapped out if it is ever reused. When there's no replacement 689 // considered swapped out if it is ever reused. When there's no replacement
690 // proxy, this doesn't really matter, as the RenderViewHost will be destroyed 690 // proxy, this doesn't really matter, as the RenderViewHost will be destroyed
691 // shortly, since |render_frame_host| is its last active frame and will be 691 // shortly, since |render_frame_host| is its last active frame and will be
692 // deleted below. See https://crbug.com/627400. 692 // deleted below. See https://crbug.com/627400.
693 if (frame_tree_node_->IsMainFrame()) { 693 if (frame_tree_node_->IsMainFrame()) {
694 rvh->set_main_frame_routing_id(MSG_ROUTING_NONE); 694 rvh->set_main_frame_routing_id(MSG_ROUTING_NONE);
695 rvh->set_is_active(false); 695 rvh->set_is_active(false);
696 rvh->set_is_swapped_out(true); 696 rvh->set_is_swapped_out(true);
697
698 if (rvh->GetWidget()->GetView()) {
699 rvh->GetWidget()->GetView()->Destroy();
700 rvh->GetWidget()->SetView(nullptr);
701 }
697 } 702 }
698 703
699 render_frame_host.reset(); 704 render_frame_host.reset();
700 705
701 // If a new RenderFrameProxyHost was created above, or if the old proxy isn't 706 // If a new RenderFrameProxyHost was created above, or if the old proxy isn't
702 // live, create the RenderFrameProxy in the renderer, so that other frames 707 // live, create the RenderFrameProxy in the renderer, so that other frames
703 // can still communicate with this frame. See https://crbug.com/653746. 708 // can still communicate with this frame. See https://crbug.com/653746.
704 if (proxy && !proxy->is_render_frame_proxy_live()) 709 if (proxy && !proxy->is_render_frame_proxy_live())
705 proxy->InitRenderFrameProxy(); 710 proxy->InitRenderFrameProxy();
706 } 711 }
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, hidden, 1744 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, hidden,
1740 false); 1745 false);
1741 RenderViewHostImpl* render_view_host = 1746 RenderViewHostImpl* render_view_host =
1742 new_render_frame_host->render_view_host(); 1747 new_render_frame_host->render_view_host();
1743 1748
1744 // Prevent the process from exiting while we're trying to navigate in it. 1749 // Prevent the process from exiting while we're trying to navigate in it.
1745 new_render_frame_host->GetProcess()->AddPendingView(); 1750 new_render_frame_host->GetProcess()->AddPendingView();
1746 1751
1747 if (frame_tree_node_->IsMainFrame()) { 1752 if (frame_tree_node_->IsMainFrame()) {
1748 success = InitRenderView(render_view_host, proxy); 1753 success = InitRenderView(render_view_host, proxy);
1749
1750 // If we are reusing the RenderViewHost and it doesn't already have a
1751 // RenderWidgetHostView, we need to create one if this is the main frame.
1752 if (!render_view_host->GetWidget()->GetView())
lfg 2016/11/15 04:37:34 I moved this to CommitPending so it's easier to re
Charlie Reis 2016/11/15 19:59:05 Sounds good-- I like the symmetry. We don't actua
lfg 2016/11/23 00:27:04 Right.
1753 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host);
1754 } else { 1754 } else {
1755 DCHECK(render_view_host->IsRenderViewLive()); 1755 DCHECK(render_view_host->IsRenderViewLive());
1756 } 1756 }
1757 1757
1758 if (success) { 1758 if (success) {
1759 if (frame_tree_node_->IsMainFrame()) { 1759 if (frame_tree_node_->IsMainFrame()) {
1760 // Don't show the main frame's view until we get a DidNavigate from it. 1760 // Don't show the main frame's view until we get a DidNavigate from it.
1761 // Only the RenderViewHost for the top-level RenderFrameHost has a 1761 // Only the RenderViewHost for the top-level RenderFrameHost has a
1762 // RenderWidgetHostView; RenderWidgetHosts for out-of-process iframes 1762 // RenderWidgetHostView; RenderWidgetHosts for out-of-process iframes
1763 // will be created later and hidden. 1763 // will be created later and hidden.
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 } else { 2144 } else {
2145 // PlzNavigate 2145 // PlzNavigate
2146 DCHECK(speculative_render_frame_host_); 2146 DCHECK(speculative_render_frame_host_);
2147 old_render_frame_host = 2147 old_render_frame_host =
2148 SetRenderFrameHost(std::move(speculative_render_frame_host_)); 2148 SetRenderFrameHost(std::move(speculative_render_frame_host_));
2149 } 2149 }
2150 2150
2151 // The process will no longer try to exit, so we can decrement the count. 2151 // The process will no longer try to exit, so we can decrement the count.
2152 render_frame_host_->GetProcess()->RemovePendingView(); 2152 render_frame_host_->GetProcess()->RemovePendingView();
2153 2153
2154 // The RenderViewHost keeps track of the main RenderFrameHost routing id.
2155 // If this is committing a main frame navigation, update it and set the
2156 // routing id in the RenderViewHost associated with the old RenderFrameHost
2157 // to MSG_ROUTING_NONE.
2158 if (is_main_frame) {
2159 RenderViewHostImpl* rvh = render_frame_host_->render_view_host();
2160 rvh->set_main_frame_routing_id(render_frame_host_->routing_id());
2161
2162 // If we are reusing the RenderViewHost, we need to create the
2163 // RenderWidgetHostView if this is the main frame.
2164 if (rvh->IsRenderViewLive() && rvh->is_swapped_out())
Charlie Reis 2016/11/15 19:59:05 The is_swapped_out clause here is new. If we keep
alexmos 2016/11/17 17:55:57 Is the logic that if the RVH is reused and transit
alexmos 2016/11/17 17:55:57 Is the IsRenderViewLive check necessary? How woul
lfg 2016/11/23 00:27:04 I've switched so that the lifetime of RWHV now tra
lfg 2016/11/23 00:27:04 I wasn't able to figure out when IsRenderViewLive
alexmos 2016/11/23 17:54:45 Ack. I'm not sure myself, but good point about li
2165 delegate_->CreateRenderWidgetHostViewForRenderManager(rvh);
2166
2167 // If the RenderViewHost is transitioning from swapped out to active state,
2168 // it was reused, so dispatch a RenderViewReady event. For example, this
2169 // is necessary to hide the sad tab if one is currently displayed. See
2170 // https://crbug.com/591984.
2171 //
2172 // TODO(alexmos): Remove this and move RenderViewReady consumers to use
2173 // the main frame's RenderFrameCreated instead.
2174 if (!rvh->is_active())
2175 rvh->PostRenderViewReady();
2176
2177 rvh->set_is_active(true);
Charlie Reis 2016/11/15 19:59:05 I see this was just moved from below, but I'm noti
alexmos 2016/11/17 17:55:57 They are not redundant -- these are updating the n
lfg 2016/11/23 00:27:04 I've moved the code that sets the old RVH's active
2178 rvh->set_is_swapped_out(false);
2179 old_render_frame_host->render_view_host()->set_main_frame_routing_id(
2180 MSG_ROUTING_NONE);
2181 }
2182
2154 // Show the new view (or a sad tab) if necessary. 2183 // Show the new view (or a sad tab) if necessary.
2155 bool new_rfh_has_view = !!render_frame_host_->GetView(); 2184 bool new_rfh_has_view = !!render_frame_host_->GetView();
2156 if (!delegate_->IsHidden() && new_rfh_has_view) { 2185 if (!delegate_->IsHidden() && new_rfh_has_view) {
2157 // In most cases, we need to show the new view. 2186 // In most cases, we need to show the new view.
2158 render_frame_host_->GetView()->Show(); 2187 render_frame_host_->GetView()->Show();
2159 } 2188 }
2160 if (!new_rfh_has_view) { 2189 if (!new_rfh_has_view) {
2161 // If the view is gone, then this RenderViewHost died while it was hidden. 2190 // If the view is gone, then this RenderViewHost died while it was hidden.
2162 // We ignored the RenderProcessGone call at the time, so we should send it 2191 // We ignored the RenderProcessGone call at the time, so we should send it
2163 // now to make sure the sad tab shows up, etc. 2192 // now to make sure the sad tab shows up, etc.
2164 DCHECK(!render_frame_host_->IsRenderFrameLive()); 2193 DCHECK(!render_frame_host_->IsRenderFrameLive());
2165 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive()); 2194 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive());
2166 render_frame_host_->ResetLoadingState(); 2195 render_frame_host_->ResetLoadingState();
2167 delegate_->RenderProcessGoneFromRenderManager( 2196 delegate_->RenderProcessGoneFromRenderManager(
2168 render_frame_host_->render_view_host()); 2197 render_frame_host_->render_view_host());
2169 } 2198 }
2170 2199
2171 // For top-level frames, also hide the old RenderViewHost's view.
2172 // TODO(creis): As long as show/hide are on RVH, we don't want to hide on
2173 // subframe navigations or we will interfere with the top-level frame.
2174 if (is_main_frame &&
2175 old_render_frame_host->render_view_host()->GetWidget()->GetView()) {
2176 old_render_frame_host->render_view_host()->GetWidget()->GetView()->Hide();
2177 }
2178
2179 // Make sure the size is up to date. (Fix for bug 1079768.) 2200 // Make sure the size is up to date. (Fix for bug 1079768.)
2180 delegate_->UpdateRenderViewSizeForRenderManager(); 2201 delegate_->UpdateRenderViewSizeForRenderManager();
2181 2202
2182 if (will_focus_location_bar) { 2203 if (will_focus_location_bar) {
2183 delegate_->SetFocusToLocationBar(false); 2204 delegate_->SetFocusToLocationBar(false);
2184 } else if (focus_render_view && render_frame_host_->GetView()) { 2205 } else if (focus_render_view && render_frame_host_->GetView()) {
2185 if (is_main_frame) { 2206 if (is_main_frame) {
2186 render_frame_host_->GetView()->Focus(); 2207 render_frame_host_->GetView()->Focus();
2187 } else { 2208 } else {
2188 // The main frame's view is already focused, but we need to set 2209 // The main frame's view is already focused, but we need to set
2189 // page-level focus in the subframe's renderer. 2210 // page-level focus in the subframe's renderer.
2190 frame_tree_node_->frame_tree()->SetPageFocus( 2211 frame_tree_node_->frame_tree()->SetPageFocus(
2191 render_frame_host_->GetSiteInstance(), true); 2212 render_frame_host_->GetSiteInstance(), true);
2192 } 2213 }
2193 } 2214 }
2194 2215
2195 // Notify that we've swapped RenderFrameHosts. We do this before shutting down 2216 // Notify that we've swapped RenderFrameHosts. We do this before shutting down
2196 // the RFH so that we can clean up RendererResources related to the RFH first. 2217 // the RFH so that we can clean up RendererResources related to the RFH first.
2197 delegate_->NotifySwappedFromRenderManager( 2218 delegate_->NotifySwappedFromRenderManager(
2198 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); 2219 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame);
2199 2220
2200 // The RenderViewHost keeps track of the main RenderFrameHost routing id.
2201 // If this is committing a main frame navigation, update it and set the
2202 // routing id in the RenderViewHost associated with the old RenderFrameHost
2203 // to MSG_ROUTING_NONE.
2204 if (is_main_frame) {
2205 RenderViewHostImpl* rvh = render_frame_host_->render_view_host();
2206 rvh->set_main_frame_routing_id(render_frame_host_->routing_id());
2207
2208 // If the RenderViewHost is transitioning from swapped out to active state,
2209 // it was reused, so dispatch a RenderViewReady event. For example, this
2210 // is necessary to hide the sad tab if one is currently displayed. See
2211 // https://crbug.com/591984.
2212 //
2213 // TODO(alexmos): Remove this and move RenderViewReady consumers to use
2214 // the main frame's RenderFrameCreated instead.
2215 if (!rvh->is_active())
2216 rvh->PostRenderViewReady();
2217
2218 rvh->set_is_active(true);
2219 rvh->set_is_swapped_out(false);
2220 old_render_frame_host->render_view_host()->set_main_frame_routing_id(
2221 MSG_ROUTING_NONE);
2222 }
2223
2224 // Swap out the old frame now that the new one is visible. 2221 // Swap out the old frame now that the new one is visible.
2225 // This will swap it out and schedule it for deletion when the swap out ack 2222 // This will swap it out and schedule it for deletion when the swap out ack
2226 // arrives (or immediately if the process isn't live). 2223 // arrives (or immediately if the process isn't live).
2227 SwapOutOldFrame(std::move(old_render_frame_host)); 2224 SwapOutOldFrame(std::move(old_render_frame_host));
2228 2225
2229 // Since the new RenderFrameHost is now committed, there must be no proxies 2226 // Since the new RenderFrameHost is now committed, there must be no proxies
2230 // for its SiteInstance. Delete any existing ones. 2227 // for its SiteInstance. Delete any existing ones.
2231 DeleteRenderFrameProxyHost(render_frame_host_->GetSiteInstance()); 2228 DeleteRenderFrameProxyHost(render_frame_host_->GetSiteInstance());
2232 2229
2233 // If this is a subframe, it should have a CrossProcessFrameConnector 2230 // If this is a subframe, it should have a CrossProcessFrameConnector
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
2722 resolved_url)) { 2719 resolved_url)) {
2723 DCHECK(!dest_instance || 2720 DCHECK(!dest_instance ||
2724 dest_instance == render_frame_host_->GetSiteInstance()); 2721 dest_instance == render_frame_host_->GetSiteInstance());
2725 return false; 2722 return false;
2726 } 2723 }
2727 2724
2728 return true; 2725 return true;
2729 } 2726 }
2730 2727
2731 } // namespace content 2728 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698