| 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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "content/browser/child_process_security_policy_impl.h" | 13 #include "content/browser/child_process_security_policy_impl.h" |
| 14 #include "content/browser/devtools/render_view_devtools_agent_host.h" | 14 #include "content/browser/devtools/render_view_devtools_agent_host.h" |
| 15 #include "content/browser/frame_host/cross_process_frame_connector.h" | 15 #include "content/browser/frame_host/cross_process_frame_connector.h" |
| 16 #include "content/browser/frame_host/cross_site_transferring_request.h" | 16 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 17 #include "content/browser/frame_host/debug_urls.h" | 17 #include "content/browser/frame_host/debug_urls.h" |
| 18 #include "content/browser/frame_host/interstitial_page_impl.h" | 18 #include "content/browser/frame_host/interstitial_page_impl.h" |
| 19 #include "content/browser/frame_host/navigation_controller_impl.h" | 19 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 20 #include "content/browser/frame_host/navigation_entry_impl.h" | 20 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 21 #include "content/browser/frame_host/navigator.h" | 21 #include "content/browser/frame_host/navigator.h" |
| 22 #include "content/browser/frame_host/render_frame_host_factory.h" | 22 #include "content/browser/frame_host/render_frame_host_factory.h" |
| 23 #include "content/browser/frame_host/render_frame_host_impl.h" | 23 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 24 #include "content/browser/frame_host/render_frame_proxy_host.h" | 24 #include "content/browser/frame_host/render_frame_proxy_host.h" |
| 25 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | |
| 26 #include "content/browser/renderer_host/render_process_host_impl.h" | 25 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 27 #include "content/browser/renderer_host/render_view_host_factory.h" | 26 #include "content/browser/renderer_host/render_view_host_factory.h" |
| 28 #include "content/browser/renderer_host/render_view_host_impl.h" | 27 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 29 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 28 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| 30 #include "content/browser/site_instance_impl.h" | 29 #include "content/browser/site_instance_impl.h" |
| 31 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 30 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 32 #include "content/browser/webui/web_ui_impl.h" | 31 #include "content/browser/webui/web_ui_impl.h" |
| 33 #include "content/common/view_messages.h" | 32 #include "content/common/view_messages.h" |
| 34 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
| 35 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_types.h" | 35 #include "content/public/browser/notification_types.h" |
| 37 #include "content/public/browser/render_widget_host_iterator.h" | 36 #include "content/public/browser/render_widget_host_iterator.h" |
| 38 #include "content/public/browser/render_widget_host_view.h" | |
| 39 #include "content/public/browser/user_metrics.h" | 37 #include "content/public/browser/user_metrics.h" |
| 40 #include "content/public/browser/web_ui_controller.h" | 38 #include "content/public/browser/web_ui_controller.h" |
| 41 #include "content/public/common/content_switches.h" | 39 #include "content/public/common/content_switches.h" |
| 42 #include "content/public/common/url_constants.h" | 40 #include "content/public/common/url_constants.h" |
| 43 | 41 |
| 44 namespace content { | 42 namespace content { |
| 45 | 43 |
| 46 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( | 44 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( |
| 47 const GlobalRequestID& global_request_id, | 45 const GlobalRequestID& global_request_id, |
| 48 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, | 46 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 169 |
| 172 // If the current render_frame_host_ isn't live, we should create it so | 170 // If the current render_frame_host_ isn't live, we should create it so |
| 173 // that we don't show a sad tab while the dest_render_frame_host fetches | 171 // that we don't show a sad tab while the dest_render_frame_host fetches |
| 174 // its first page. (Bug 1145340) | 172 // its first page. (Bug 1145340) |
| 175 if (dest_render_frame_host != render_frame_host_ && | 173 if (dest_render_frame_host != render_frame_host_ && |
| 176 !render_frame_host_->render_view_host()->IsRenderViewLive()) { | 174 !render_frame_host_->render_view_host()->IsRenderViewLive()) { |
| 177 // Note: we don't call InitRenderView here because we are navigating away | 175 // Note: we don't call InitRenderView here because we are navigating away |
| 178 // soon anyway, and we don't have the NavigationEntry for this host. | 176 // soon anyway, and we don't have the NavigationEntry for this host. |
| 179 delegate_->CreateRenderViewForRenderManager( | 177 delegate_->CreateRenderViewForRenderManager( |
| 180 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, | 178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, |
| 181 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame()); | 179 MSG_ROUTING_NONE, NULL); |
| 182 } | 180 } |
| 183 | 181 |
| 184 // If the renderer crashed, then try to create a new one to satisfy this | 182 // If the renderer crashed, then try to create a new one to satisfy this |
| 185 // navigation request. | 183 // navigation request. |
| 186 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { | 184 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { |
| 187 // Recreate the opener chain. | 185 // Recreate the opener chain. |
| 188 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | 186 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( |
| 189 dest_render_frame_host->GetSiteInstance()); | 187 dest_render_frame_host->GetSiteInstance()); |
| 190 if (!InitRenderView(dest_render_frame_host->render_view_host(), | 188 if (!InitRenderView(dest_render_frame_host->render_view_host(), |
| 191 opener_route_id, | 189 opener_route_id, MSG_ROUTING_NONE)) |
| 192 MSG_ROUTING_NONE, | |
| 193 frame_tree_node_->IsMainFrame())) | |
| 194 return NULL; | 190 return NULL; |
| 195 | 191 |
| 196 // Now that we've created a new renderer, be sure to hide it if it isn't | 192 // Now that we've created a new renderer, be sure to hide it if it isn't |
| 197 // our primary one. Otherwise, we might crash if we try to call Show() | 193 // our primary one. Otherwise, we might crash if we try to call Show() |
| 198 // on it later. | 194 // on it later. |
| 199 if (dest_render_frame_host != render_frame_host_ && | 195 if (dest_render_frame_host != render_frame_host_ && |
| 200 dest_render_frame_host->render_view_host()->GetView()) { | 196 dest_render_frame_host->render_view_host()->GetView()) { |
| 201 dest_render_frame_host->render_view_host()->GetView()->Hide(); | 197 dest_render_frame_host->render_view_host()->GetView()->Hide(); |
| 202 } else if (frame_tree_node_->IsMainFrame()) { | 198 } else if (frame_tree_node_->IsMainFrame()) { |
| 203 // This is our primary renderer, notify here as we won't be calling | 199 // This is our primary renderer, notify here as we won't be calling |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 | 494 |
| 499 if (!frame_tree_node_->IsMainFrame()) { | 495 if (!frame_tree_node_->IsMainFrame()) { |
| 500 // The RenderFrameHost being swapped out becomes the proxy for this | 496 // The RenderFrameHost being swapped out becomes the proxy for this |
| 501 // frame in its parent's process. CrossProcessFrameConnector | 497 // frame in its parent's process. CrossProcessFrameConnector |
| 502 // initialization only needs to happen on an initial cross-process | 498 // initialization only needs to happen on an initial cross-process |
| 503 // navigation, when the RenderFrame leaves the same process as its parent. | 499 // navigation, when the RenderFrame leaves the same process as its parent. |
| 504 // The same CrossProcessFrameConnector is used for subsequent cross- | 500 // The same CrossProcessFrameConnector is used for subsequent cross- |
| 505 // process navigations, but it will be destroyed if the Frame is | 501 // process navigations, but it will be destroyed if the Frame is |
| 506 // navigated back to the same site instance as its parent. | 502 // navigated back to the same site instance as its parent. |
| 507 // TODO(kenrb): This will change when RenderFrameProxyHost is created. | 503 // TODO(kenrb): This will change when RenderFrameProxyHost is created. |
| 508 // TODO(nasko): Move CrossProcessFrameConnector to be owned by | |
| 509 // RenderFrameProxyHost instead of RenderFrameHostManager once proxy | |
| 510 // support lands. | |
| 511 if (!cross_process_frame_connector_) { | 504 if (!cross_process_frame_connector_) { |
| 512 cross_process_frame_connector_ = | 505 cross_process_frame_connector_ = |
| 513 new CrossProcessFrameConnector(render_frame_host_.get()); | 506 new CrossProcessFrameConnector(render_frame_host_.get()); |
| 514 } | 507 } |
| 515 } | 508 } |
| 516 | 509 |
| 517 // Create the RenderFrameProxyHost that will replace the | 510 // Create the RenderFrameProxyHost that will replace the |
| 518 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted | 511 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted |
| 519 // from the map and not leaked. | 512 // from the map and not leaked. |
| 520 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( | 513 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 new_render_frame_host->GetProcess()->AddPendingView(); | 958 new_render_frame_host->GetProcess()->AddPendingView(); |
| 966 } else { | 959 } else { |
| 967 proxy = new RenderFrameProxyHost( | 960 proxy = new RenderFrameProxyHost( |
| 968 new_render_frame_host->GetSiteInstance(), frame_tree_node_); | 961 new_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 969 proxy_hosts_[instance->GetId()] = proxy; | 962 proxy_hosts_[instance->GetId()] = proxy; |
| 970 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); | 963 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); |
| 971 proxy_routing_id = proxy->GetRoutingID(); | 964 proxy_routing_id = proxy->GetRoutingID(); |
| 972 } | 965 } |
| 973 | 966 |
| 974 bool success = InitRenderView( | 967 bool success = InitRenderView( |
| 975 render_view_host, opener_route_id, proxy_routing_id, | 968 render_view_host, opener_route_id, proxy_routing_id); |
| 976 frame_tree_node_->IsMainFrame()); | |
| 977 if (success && frame_tree_node_->IsMainFrame()) { | 969 if (success && frame_tree_node_->IsMainFrame()) { |
| 978 // Don't show the main frame's view until we get a DidNavigate from it. | 970 // Don't show the main frame's view until we get a DidNavigate from it. |
| 979 render_view_host->GetView()->Hide(); | 971 render_view_host->GetView()->Hide(); |
| 980 } else if (!swapped_out && pending_render_frame_host_) { | 972 } else if (!swapped_out && pending_render_frame_host_) { |
| 981 CancelPending(); | 973 CancelPending(); |
| 982 } | 974 } |
| 983 routing_id = render_view_host->GetRoutingID(); | 975 routing_id = render_view_host->GetRoutingID(); |
| 984 } | 976 } |
| 985 | 977 |
| 986 // Use this as our new pending RFH if it isn't swapped out. | 978 // Use this as our new pending RFH if it isn't swapped out. |
| 987 if (!swapped_out) | 979 if (!swapped_out) |
| 988 pending_render_frame_host_ = new_render_frame_host.Pass(); | 980 pending_render_frame_host_ = new_render_frame_host.Pass(); |
| 989 | 981 |
| 990 return routing_id; | 982 return routing_id; |
| 991 } | 983 } |
| 992 | 984 |
| 993 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, | 985 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, |
| 994 int opener_route_id, | 986 int opener_route_id, |
| 995 int proxy_routing_id, | 987 int proxy_routing_id) { |
| 996 bool for_main_frame) { | |
| 997 // We may have initialized this RenderViewHost for another RenderFrameHost. | 988 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 998 if (render_view_host->IsRenderViewLive()) | 989 if (render_view_host->IsRenderViewLive()) |
| 999 return true; | 990 return true; |
| 1000 | 991 |
| 1001 // If the pending navigation is to a WebUI and the RenderView is not in a | 992 // If the pending navigation is to a WebUI and the RenderView is not in a |
| 1002 // guest process, tell the RenderViewHost about any bindings it will need | 993 // guest process, tell the RenderViewHost about any bindings it will need |
| 1003 // enabled. | 994 // enabled. |
| 1004 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { | 995 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { |
| 1005 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 996 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
| 1006 } else { | 997 } else { |
| 1007 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 998 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
| 1008 // process unless it's swapped out. | 999 // process unless it's swapped out. |
| 1009 RenderViewHostImpl* rvh_impl = | 1000 RenderViewHostImpl* rvh_impl = |
| 1010 static_cast<RenderViewHostImpl*>(render_view_host); | 1001 static_cast<RenderViewHostImpl*>(render_view_host); |
| 1011 if (!rvh_impl->IsSwappedOut()) { | 1002 if (!rvh_impl->IsSwappedOut()) { |
| 1012 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1003 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
| 1013 render_view_host->GetProcess()->GetID())); | 1004 render_view_host->GetProcess()->GetID())); |
| 1014 } | 1005 } |
| 1015 } | 1006 } |
| 1016 | 1007 |
| 1017 return delegate_->CreateRenderViewForRenderManager( | 1008 return delegate_->CreateRenderViewForRenderManager( |
| 1018 render_view_host, opener_route_id, proxy_routing_id, for_main_frame); | 1009 render_view_host, opener_route_id, proxy_routing_id, |
| 1010 cross_process_frame_connector_); |
| 1019 } | 1011 } |
| 1020 | 1012 |
| 1021 void RenderFrameHostManager::CommitPending() { | 1013 void RenderFrameHostManager::CommitPending() { |
| 1022 // First check whether we're going to want to focus the location bar after | 1014 // First check whether we're going to want to focus the location bar after |
| 1023 // this commit. We do this now because the navigation hasn't formally | 1015 // this commit. We do this now because the navigation hasn't formally |
| 1024 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1016 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 1025 // this triggers won't be able to figure out what's going on. | 1017 // this triggers won't be able to figure out what's going on. |
| 1026 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1018 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 1027 | 1019 |
| 1028 // We expect SwapOutOldPage to have canceled any modal dialogs and told the | 1020 // We expect SwapOutOldPage to have canceled any modal dialogs and told the |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 | 1157 |
| 1166 RenderFrameProxyHostMap::iterator iter = | 1158 RenderFrameProxyHostMap::iterator iter = |
| 1167 proxy_hosts_.find(old_site_instance_id); | 1159 proxy_hosts_.find(old_site_instance_id); |
| 1168 CHECK(iter != proxy_hosts_.end()); | 1160 CHECK(iter != proxy_hosts_.end()); |
| 1169 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); | 1161 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 1170 | 1162 |
| 1171 // If there are no active views in this SiteInstance, it means that | 1163 // If there are no active views in this SiteInstance, it means that |
| 1172 // this RFH was the last active one in the SiteInstance. Now that we | 1164 // this RFH was the last active one in the SiteInstance. Now that we |
| 1173 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs | 1165 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
| 1174 // in this SiteInstance. | 1166 // in this SiteInstance. |
| 1175 if (!active_view_count) { | 1167 if (!active_view_count) |
| 1176 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1168 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
| 1177 } else { | |
| 1178 // If this is a subframe, it should have a CrossProcessFrameConnector | |
| 1179 // created already and we just need to link it to the proper view in the | |
| 1180 // new process. | |
| 1181 if (!is_main_frame) { | |
| 1182 RenderWidgetHostView* rwhv = | |
| 1183 render_frame_host_->render_view_host()->GetView(); | |
| 1184 RenderWidgetHostViewChildFrame* rwhv_child = | |
| 1185 static_cast<RenderWidgetHostViewChildFrame*>(rwhv); | |
| 1186 cross_process_frame_connector_->set_view(rwhv_child); | |
| 1187 } | |
| 1188 } | |
| 1189 } | 1169 } |
| 1190 } | 1170 } |
| 1191 | 1171 |
| 1192 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1172 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
| 1193 int32 site_instance_id) { | 1173 int32 site_instance_id) { |
| 1194 // First remove any swapped out RFH for this SiteInstance from our own list. | 1174 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1195 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1175 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1196 | 1176 |
| 1197 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1177 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
| 1198 // in the SiteInstance, then tell their respective FrameTrees to remove all | 1178 // in the SiteInstance, then tell their respective FrameTrees to remove all |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 SiteInstance* instance) const { | 1450 SiteInstance* instance) const { |
| 1471 RenderFrameProxyHostMap::const_iterator iter = | 1451 RenderFrameProxyHostMap::const_iterator iter = |
| 1472 proxy_hosts_.find(instance->GetId()); | 1452 proxy_hosts_.find(instance->GetId()); |
| 1473 if (iter != proxy_hosts_.end()) | 1453 if (iter != proxy_hosts_.end()) |
| 1474 return iter->second; | 1454 return iter->second; |
| 1475 | 1455 |
| 1476 return NULL; | 1456 return NULL; |
| 1477 } | 1457 } |
| 1478 | 1458 |
| 1479 } // namespace content | 1459 } // namespace content |
| OLD | NEW |