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

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

Issue 270883003: Decouple RVH creation from CrossProcessFrameConnector. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months 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 | Annotate | Revision Log
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 <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "content/browser/child_process_security_policy_impl.h" 12 #include "content/browser/child_process_security_policy_impl.h"
13 #include "content/browser/devtools/render_view_devtools_agent_host.h" 13 #include "content/browser/devtools/render_view_devtools_agent_host.h"
14 #include "content/browser/frame_host/cross_process_frame_connector.h" 14 #include "content/browser/frame_host/cross_process_frame_connector.h"
15 #include "content/browser/frame_host/cross_site_transferring_request.h" 15 #include "content/browser/frame_host/cross_site_transferring_request.h"
16 #include "content/browser/frame_host/debug_urls.h" 16 #include "content/browser/frame_host/debug_urls.h"
17 #include "content/browser/frame_host/interstitial_page_impl.h" 17 #include "content/browser/frame_host/interstitial_page_impl.h"
18 #include "content/browser/frame_host/navigation_controller_impl.h" 18 #include "content/browser/frame_host/navigation_controller_impl.h"
19 #include "content/browser/frame_host/navigation_entry_impl.h" 19 #include "content/browser/frame_host/navigation_entry_impl.h"
20 #include "content/browser/frame_host/navigator.h" 20 #include "content/browser/frame_host/navigator.h"
21 #include "content/browser/frame_host/render_frame_host_factory.h" 21 #include "content/browser/frame_host/render_frame_host_factory.h"
22 #include "content/browser/frame_host/render_frame_host_impl.h" 22 #include "content/browser/frame_host/render_frame_host_impl.h"
23 #include "content/browser/frame_host/render_frame_proxy_host.h" 23 #include "content/browser/frame_host/render_frame_proxy_host.h"
24 #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
24 #include "content/browser/renderer_host/render_process_host_impl.h" 25 #include "content/browser/renderer_host/render_process_host_impl.h"
25 #include "content/browser/renderer_host/render_view_host_factory.h" 26 #include "content/browser/renderer_host/render_view_host_factory.h"
26 #include "content/browser/renderer_host/render_view_host_impl.h" 27 #include "content/browser/renderer_host/render_view_host_impl.h"
27 #include "content/browser/renderer_host/render_widget_host_view_base.h" 28 #include "content/browser/renderer_host/render_widget_host_view_base.h"
28 #include "content/browser/site_instance_impl.h" 29 #include "content/browser/site_instance_impl.h"
29 #include "content/browser/webui/web_ui_controller_factory_registry.h" 30 #include "content/browser/webui/web_ui_controller_factory_registry.h"
30 #include "content/browser/webui/web_ui_impl.h" 31 #include "content/browser/webui/web_ui_impl.h"
31 #include "content/common/view_messages.h" 32 #include "content/common/view_messages.h"
32 #include "content/public/browser/content_browser_client.h" 33 #include "content/public/browser/content_browser_client.h"
33 #include "content/public/browser/notification_service.h" 34 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_types.h" 35 #include "content/public/browser/notification_types.h"
35 #include "content/public/browser/render_widget_host_iterator.h" 36 #include "content/public/browser/render_widget_host_iterator.h"
37 #include "content/public/browser/render_widget_host_view.h"
36 #include "content/public/browser/user_metrics.h" 38 #include "content/public/browser/user_metrics.h"
37 #include "content/public/browser/web_ui_controller.h" 39 #include "content/public/browser/web_ui_controller.h"
38 #include "content/public/common/content_switches.h" 40 #include "content/public/common/content_switches.h"
39 #include "content/public/common/url_constants.h" 41 #include "content/public/common/url_constants.h"
40 42
41 namespace content { 43 namespace content {
42 44
43 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( 45 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams(
44 const GlobalRequestID& global_request_id, 46 const GlobalRequestID& global_request_id,
45 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, 47 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 return NULL; // We weren't able to create a pending render frame host. 173 return NULL; // We weren't able to create a pending render frame host.
172 174
173 // If the current render_frame_host_ isn't live, we should create it so 175 // If the current render_frame_host_ isn't live, we should create it so
174 // that we don't show a sad tab while the dest_render_frame_host fetches 176 // that we don't show a sad tab while the dest_render_frame_host fetches
175 // its first page. (Bug 1145340) 177 // its first page. (Bug 1145340)
176 if (dest_render_frame_host != render_frame_host_ && 178 if (dest_render_frame_host != render_frame_host_ &&
177 !render_frame_host_->render_view_host()->IsRenderViewLive()) { 179 !render_frame_host_->render_view_host()->IsRenderViewLive()) {
178 // Note: we don't call InitRenderView here because we are navigating away 180 // Note: we don't call InitRenderView here because we are navigating away
179 // soon anyway, and we don't have the NavigationEntry for this host. 181 // soon anyway, and we don't have the NavigationEntry for this host.
180 delegate_->CreateRenderViewForRenderManager( 182 delegate_->CreateRenderViewForRenderManager(
181 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, NULL); 183 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, false);
182 } 184 }
183 185
184 // If the renderer crashed, then try to create a new one to satisfy this 186 // If the renderer crashed, then try to create a new one to satisfy this
185 // navigation request. 187 // navigation request.
186 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { 188 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) {
187 // Recreate the opener chain. 189 // Recreate the opener chain.
188 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 190 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
189 dest_render_frame_host->GetSiteInstance()); 191 dest_render_frame_host->GetSiteInstance());
190 if (!InitRenderView(dest_render_frame_host->render_view_host(), 192 if (!InitRenderView(dest_render_frame_host->render_view_host(),
191 opener_route_id)) 193 opener_route_id, false))
192 return NULL; 194 return NULL;
193 195
194 // Now that we've created a new renderer, be sure to hide it if it isn't 196 // Now that we've created a new renderer, be sure to hide it if it isn't
195 // our primary one. Otherwise, we might crash if we try to call Show() 197 // our primary one. Otherwise, we might crash if we try to call Show()
196 // on it later. 198 // on it later.
197 if (dest_render_frame_host != render_frame_host_ && 199 if (dest_render_frame_host != render_frame_host_ &&
198 dest_render_frame_host->render_view_host()->GetView()) { 200 dest_render_frame_host->render_view_host()->GetView()) {
199 dest_render_frame_host->render_view_host()->GetView()->Hide(); 201 dest_render_frame_host->render_view_host()->GetView()->Hide();
200 } else if (frame_tree_node_->IsMainFrame()) { 202 } else if (frame_tree_node_->IsMainFrame()) {
201 // This is our primary renderer, notify here as we won't be calling 203 // This is our primary renderer, notify here as we won't be calling
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 475
474 // Now delete them. 476 // Now delete them.
475 while (!ids_to_remove.empty()) { 477 while (!ids_to_remove.empty()) {
476 delete proxy_hosts_[ids_to_remove.back()]; 478 delete proxy_hosts_[ids_to_remove.back()];
477 proxy_hosts_.erase(ids_to_remove.back()); 479 proxy_hosts_.erase(ids_to_remove.back());
478 ids_to_remove.pop_back(); 480 ids_to_remove.pop_back();
479 } 481 }
480 } 482 }
481 483
482 void RenderFrameHostManager::SwapOutOldPage() { 484 void RenderFrameHostManager::SwapOutOldPage() {
485 LOG(ERROR) << "RFHM::SwapOutOldPage[" << this << "]";
483 // Should only see this while we have a pending renderer or transfer. 486 // Should only see this while we have a pending renderer or transfer.
484 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); 487 CHECK(cross_navigation_pending_ || pending_nav_params_.get());
485 488
486 // Tell the renderer to suppress any further modal dialogs so that we can swap 489 // Tell the renderer to suppress any further modal dialogs so that we can swap
487 // it out. This must be done before canceling any current dialog, in case 490 // it out. This must be done before canceling any current dialog, in case
488 // there is a loop creating additional dialogs. 491 // there is a loop creating additional dialogs.
489 // TODO(creis): Handle modal dialogs in subframe processes. 492 // TODO(creis): Handle modal dialogs in subframe processes.
490 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); 493 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut();
491 494
492 // Now close any modal dialogs that would prevent us from swapping out. This 495 // Now close any modal dialogs that would prevent us from swapping out. This
493 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is 496 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is
494 // no longer on the stack when we send the SwapOut message. 497 // no longer on the stack when we send the SwapOut message.
495 delegate_->CancelModalDialogsForRenderManager(); 498 delegate_->CancelModalDialogsForRenderManager();
496 499
497 if (!frame_tree_node_->IsMainFrame()) {
498 // The RenderFrameHost being swapped out becomes the proxy for this
499 // frame in its parent's process. CrossProcessFrameConnector
500 // initialization only needs to happen on an initial cross-process
501 // navigation, when the RenderFrame leaves the same process as its parent.
502 // The same CrossProcessFrameConnector is used for subsequent cross-
503 // process navigations, but it will be destroyed if the Frame is
504 // navigated back to the same site instance as its parent.
505 // TODO(kenrb): This will change when RenderFrameProxyHost is created.
506 if (!cross_process_frame_connector_) {
507 cross_process_frame_connector_ =
508 new CrossProcessFrameConnector(render_frame_host_.get());
509 }
510 }
511
512 // Tell the old frame it is being swapped out. This will fire the unload 500 // Tell the old frame it is being swapped out. This will fire the unload
513 // handler in the background (without firing the beforeunload handler a second 501 // handler in the background (without firing the beforeunload handler a second
514 // time). When the navigation completes, we will send a message to the 502 // time). When the navigation completes, we will send a message to the
515 // ResourceDispatcherHost, allowing the pending RVH's response to resume. 503 // ResourceDispatcherHost, allowing the pending RVH's response to resume.
516 render_frame_host_->SwapOut(); 504 render_frame_host_->SwapOut();
517 505
518 // ResourceDispatcherHost has told us to run the onunload handler, which 506 // ResourceDispatcherHost has told us to run the onunload handler, which
519 // means it is not a download or unsafe page, and we are going to perform the 507 // means it is not a download or unsafe page, and we are going to perform the
520 // navigation. Thus, we no longer need to remember that the RenderFrameHost 508 // navigation. Thus, we no longer need to remember that the RenderFrameHost
521 // is part of a pending cross-site request. 509 // is part of a pending cross-site request.
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 916
929 // Prevent the process from exiting while we're trying to navigate in it. 917 // Prevent the process from exiting while we're trying to navigate in it.
930 // Otherwise, if the new RFH is swapped out already, store it. 918 // Otherwise, if the new RFH is swapped out already, store it.
931 if (!swapped_out) { 919 if (!swapped_out) {
932 new_render_frame_host->GetProcess()->AddPendingView(); 920 new_render_frame_host->GetProcess()->AddPendingView();
933 } else { 921 } else {
934 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost( 922 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost(
935 new_render_frame_host.Pass()); 923 new_render_frame_host.Pass());
936 } 924 }
937 925
938 bool success = InitRenderView(render_view_host, opener_route_id); 926 bool success = InitRenderView(
927 render_view_host, opener_route_id, frame_tree_node_->IsMainFrame());
939 if (success && frame_tree_node_->IsMainFrame()) { 928 if (success && frame_tree_node_->IsMainFrame()) {
940 // Don't show the main frame's view until we get a DidNavigate from it. 929 // Don't show the main frame's view until we get a DidNavigate from it.
941 render_view_host->GetView()->Hide(); 930 render_view_host->GetView()->Hide();
942 } else if (!swapped_out && pending_render_frame_host_) { 931 } else if (!swapped_out && pending_render_frame_host_) {
943 CancelPending(); 932 CancelPending();
944 } 933 }
945 routing_id = render_view_host->GetRoutingID(); 934 routing_id = render_view_host->GetRoutingID();
946 } 935 }
947 936
948 // Use this as our new pending RFH if it isn't swapped out. 937 // Use this as our new pending RFH if it isn't swapped out.
949 if (!swapped_out) 938 if (!swapped_out)
950 pending_render_frame_host_ = new_render_frame_host.Pass(); 939 pending_render_frame_host_ = new_render_frame_host.Pass();
951 940
952 return routing_id; 941 return routing_id;
953 } 942 }
954 943
955 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, 944 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
956 int opener_route_id) { 945 int opener_route_id,
946 bool for_subframe) {
947 LOG(ERROR) << "RFHM::InitRenderView[" << this << "]: for_subframe:"
948 << for_subframe;
957 // We may have initialized this RenderViewHost for another RenderFrameHost. 949 // We may have initialized this RenderViewHost for another RenderFrameHost.
958 if (render_view_host->IsRenderViewLive()) 950 if (render_view_host->IsRenderViewLive())
959 return true; 951 return true;
960 952
961 // If the pending navigation is to a WebUI and the RenderView is not in a 953 // If the pending navigation is to a WebUI and the RenderView is not in a
962 // guest process, tell the RenderViewHost about any bindings it will need 954 // guest process, tell the RenderViewHost about any bindings it will need
963 // enabled. 955 // enabled.
964 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { 956 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) {
965 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 957 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
966 } else { 958 } else {
967 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 959 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
968 // process unless it's swapped out. 960 // process unless it's swapped out.
969 RenderViewHostImpl* rvh_impl = 961 RenderViewHostImpl* rvh_impl =
970 static_cast<RenderViewHostImpl*>(render_view_host); 962 static_cast<RenderViewHostImpl*>(render_view_host);
971 if (!rvh_impl->IsSwappedOut()) { 963 if (!rvh_impl->IsSwappedOut()) {
972 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 964 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
973 render_view_host->GetProcess()->GetID())); 965 render_view_host->GetProcess()->GetID()));
974 } 966 }
975 } 967 }
976 968
977 return delegate_->CreateRenderViewForRenderManager( 969 return delegate_->CreateRenderViewForRenderManager(
978 render_view_host, opener_route_id, cross_process_frame_connector_); 970 render_view_host, opener_route_id, for_subframe);
979 } 971 }
980 972
981 void RenderFrameHostManager::CommitPending() { 973 void RenderFrameHostManager::CommitPending() {
974 LOG(ERROR) << "RFHM::CommitPending[" << this << "]";
982 // First check whether we're going to want to focus the location bar after 975 // First check whether we're going to want to focus the location bar after
983 // this commit. We do this now because the navigation hasn't formally 976 // this commit. We do this now because the navigation hasn't formally
984 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 977 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
985 // this triggers won't be able to figure out what's going on. 978 // this triggers won't be able to figure out what's going on.
986 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 979 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
987 980
988 // We expect SwapOutOldPage to have canceled any modal dialogs and told the 981 // We expect SwapOutOldPage to have canceled any modal dialogs and told the
989 // renderer to suppress any further dialogs until it is swapped out. However, 982 // renderer to suppress any further dialogs until it is swapped out. However,
990 // crash reports indicate that it's still possible for modal dialogs to exist 983 // crash reports indicate that it's still possible for modal dialogs to exist
991 // at this point, which poses a risk if we delete their RenderViewHost below. 984 // at this point, which poses a risk if we delete their RenderViewHost below.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 // If there are no active views in this SiteInstance, it means that 1118 // If there are no active views in this SiteInstance, it means that
1126 // this RFH was the last active one in the SiteInstance. Now that we 1119 // this RFH was the last active one in the SiteInstance. Now that we
1127 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs 1120 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs
1128 // in this SiteInstance. We do this after ensuring the RFH is on the 1121 // in this SiteInstance. We do this after ensuring the RFH is on the
1129 // swapped out list to simplify the deletion. 1122 // swapped out list to simplify the deletion.
1130 if (!static_cast<SiteInstanceImpl*>( 1123 if (!static_cast<SiteInstanceImpl*>(
1131 old_render_frame_host->GetSiteInstance())->active_view_count()) { 1124 old_render_frame_host->GetSiteInstance())->active_view_count()) {
1132 old_render_frame_host.reset(); 1125 old_render_frame_host.reset();
1133 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); 1126 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id);
1134 } else { 1127 } else {
1128 // The RenderFrameHost being swapped out becomes the proxy for this
1129 // frame in its parent's process. CrossProcessFrameConnector
1130 // initialization only needs to happen on an initial cross-process
1131 // navigation, when the RenderFrame leaves the same process as its parent.
1132 // The same CrossProcessFrameConnector is used for subsequent cross-
1133 // process navigations, but it will be destroyed if the Frame is
1134 // navigated back to the same site instance as its parent.
1135 // TODO(kenrb): This will change when RenderFrameProxyHost is created.
1136 if (!cross_process_frame_connector_) {
1137 cross_process_frame_connector_ =
1138 new CrossProcessFrameConnector(old_render_frame_host.get());
1139 RenderWidgetHostView* rwhv =
1140 old_render_frame_host->render_view_host()->GetView();
kenrb 2014/05/08 19:56:14 Which RenderViewHost does old_render_frame_host->r
1141 cross_process_frame_connector_->set_view(
1142 static_cast<RenderWidgetHostViewChildFrame*>(rwhv));
1143 }
1144
1135 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost( 1145 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost(
1136 old_render_frame_host.Pass()); 1146 old_render_frame_host.Pass());
1137 } 1147 }
1138 } 1148 }
1139 } 1149 }
1140 1150
1141 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( 1151 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance(
1142 int32 site_instance_id) { 1152 int32 site_instance_id) {
1143 // First remove any swapped out RFH for this SiteInstance from our own list. 1153 // First remove any swapped out RFH for this SiteInstance from our own list.
1144 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); 1154 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
(...skipping 18 matching lines...) Expand all
1163 &RenderFrameHostManager::ClearProxiesInSiteInstance, 1173 &RenderFrameHostManager::ClearProxiesInSiteInstance,
1164 site_instance_id)); 1174 site_instance_id));
1165 } 1175 }
1166 } 1176 }
1167 } 1177 }
1168 1178
1169 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( 1179 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
1170 const NavigationEntryImpl& entry) { 1180 const NavigationEntryImpl& entry) {
1171 // If we are currently navigating cross-process, we want to get back to normal 1181 // If we are currently navigating cross-process, we want to get back to normal
1172 // and then navigate as usual. 1182 // and then navigate as usual.
1183 LOG(ERROR) << "RFHM::UpdateStateForNavigate[" << this << "]";
1173 if (cross_navigation_pending_) { 1184 if (cross_navigation_pending_) {
1174 if (pending_render_frame_host_) 1185 if (pending_render_frame_host_)
1175 CancelPending(); 1186 CancelPending();
1176 cross_navigation_pending_ = false; 1187 cross_navigation_pending_ = false;
1177 } 1188 }
1178 1189
1179 // render_frame_host_'s SiteInstance and new_instance will not be deleted 1190 // render_frame_host_'s SiteInstance and new_instance will not be deleted
1180 // before the end of this method, so we don't have to worry about their ref 1191 // before the end of this method, so we don't have to worry about their ref
1181 // counts dropping to zero. 1192 // counts dropping to zero.
1182 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1193 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 SiteInstance* instance) const { 1434 SiteInstance* instance) const {
1424 RenderFrameProxyHostMap::const_iterator iter = 1435 RenderFrameProxyHostMap::const_iterator iter =
1425 proxy_hosts_.find(instance->GetId()); 1436 proxy_hosts_.find(instance->GetId());
1426 if (iter != proxy_hosts_.end()) 1437 if (iter != proxy_hosts_.end())
1427 return iter->second; 1438 return iter->second;
1428 1439
1429 return NULL; 1440 return NULL;
1430 } 1441 }
1431 1442
1432 } // namespace content 1443 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.h ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698