| 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" | |
| 16 #include "content/browser/frame_host/cross_site_transferring_request.h" | 15 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 17 #include "content/browser/frame_host/debug_urls.h" | 16 #include "content/browser/frame_host/debug_urls.h" |
| 18 #include "content/browser/frame_host/interstitial_page_impl.h" | 17 #include "content/browser/frame_host/interstitial_page_impl.h" |
| 19 #include "content/browser/frame_host/navigation_controller_impl.h" | 18 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 20 #include "content/browser/frame_host/navigation_entry_impl.h" | 19 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 21 #include "content/browser/frame_host/navigator.h" | 20 #include "content/browser/frame_host/navigator.h" |
| 22 #include "content/browser/frame_host/render_frame_host_factory.h" | 21 #include "content/browser/frame_host/render_frame_host_factory.h" |
| 23 #include "content/browser/frame_host/render_frame_host_impl.h" | 22 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 24 #include "content/browser/frame_host/render_frame_proxy_host.h" | 23 #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" | 24 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 27 #include "content/browser/renderer_host/render_view_host_factory.h" | 25 #include "content/browser/renderer_host/render_view_host_factory.h" |
| 28 #include "content/browser/renderer_host/render_view_host_impl.h" | 26 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 29 #include "content/browser/renderer_host/render_widget_host_view_base.h" | |
| 30 #include "content/browser/site_instance_impl.h" | 27 #include "content/browser/site_instance_impl.h" |
| 31 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 28 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 32 #include "content/browser/webui/web_ui_impl.h" | 29 #include "content/browser/webui/web_ui_impl.h" |
| 33 #include "content/common/view_messages.h" | 30 #include "content/common/view_messages.h" |
| 34 #include "content/public/browser/content_browser_client.h" | 31 #include "content/public/browser/content_browser_client.h" |
| 35 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_types.h" | 33 #include "content/public/browser/notification_types.h" |
| 37 #include "content/public/browser/render_widget_host_iterator.h" | 34 #include "content/public/browser/render_widget_host_iterator.h" |
| 38 #include "content/public/browser/render_widget_host_view.h" | 35 #include "content/public/browser/render_widget_host_view.h" |
| 39 #include "content/public/browser/user_metrics.h" | 36 #include "content/public/browser/user_metrics.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 RenderViewHostDelegate* render_view_delegate, | 70 RenderViewHostDelegate* render_view_delegate, |
| 74 RenderWidgetHostDelegate* render_widget_delegate, | 71 RenderWidgetHostDelegate* render_widget_delegate, |
| 75 Delegate* delegate) | 72 Delegate* delegate) |
| 76 : frame_tree_node_(frame_tree_node), | 73 : frame_tree_node_(frame_tree_node), |
| 77 delegate_(delegate), | 74 delegate_(delegate), |
| 78 cross_navigation_pending_(false), | 75 cross_navigation_pending_(false), |
| 79 render_frame_delegate_(render_frame_delegate), | 76 render_frame_delegate_(render_frame_delegate), |
| 80 render_view_delegate_(render_view_delegate), | 77 render_view_delegate_(render_view_delegate), |
| 81 render_widget_delegate_(render_widget_delegate), | 78 render_widget_delegate_(render_widget_delegate), |
| 82 interstitial_page_(NULL), | 79 interstitial_page_(NULL), |
| 83 cross_process_frame_connector_(NULL), | |
| 84 weak_factory_(this) { | 80 weak_factory_(this) { |
| 85 DCHECK(frame_tree_node_); | 81 DCHECK(frame_tree_node_); |
| 86 } | 82 } |
| 87 | 83 |
| 88 RenderFrameHostManager::~RenderFrameHostManager() { | 84 RenderFrameHostManager::~RenderFrameHostManager() { |
| 89 if (pending_render_frame_host_) | 85 if (pending_render_frame_host_) |
| 90 CancelPending(); | 86 CancelPending(); |
| 91 | 87 |
| 92 if (cross_process_frame_connector_) | |
| 93 delete cross_process_frame_connector_; | |
| 94 | |
| 95 // We should always have a current RenderFrameHost except in some tests. | 88 // We should always have a current RenderFrameHost except in some tests. |
| 96 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 89 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
| 97 | 90 |
| 98 // Delete any swapped out RenderFrameHosts. | 91 // Delete any swapped out RenderFrameHosts. |
| 99 STLDeleteValues(&proxy_hosts_); | 92 STLDeleteValues(&proxy_hosts_); |
| 100 } | 93 } |
| 101 | 94 |
| 102 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 95 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
| 103 SiteInstance* site_instance, | 96 SiteInstance* site_instance, |
| 104 int view_routing_id, | 97 int view_routing_id, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 } | 129 } |
| 137 | 130 |
| 138 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { | 131 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { |
| 139 if (interstitial_page_) | 132 if (interstitial_page_) |
| 140 return interstitial_page_->GetView(); | 133 return interstitial_page_->GetView(); |
| 141 if (!render_frame_host_) | 134 if (!render_frame_host_) |
| 142 return NULL; | 135 return NULL; |
| 143 return render_frame_host_->render_view_host()->GetView(); | 136 return render_frame_host_->render_view_host()->GetView(); |
| 144 } | 137 } |
| 145 | 138 |
| 139 RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() { |
| 140 if (frame_tree_node_->IsMainFrame()) |
| 141 return NULL; |
| 142 |
| 143 RenderFrameProxyHostMap::iterator iter = |
| 144 proxy_hosts_.find(frame_tree_node_->parent() |
| 145 ->render_manager() |
| 146 ->current_frame_host() |
| 147 ->GetSiteInstance() |
| 148 ->GetId()); |
| 149 if (iter == proxy_hosts_.end()) |
| 150 return NULL; |
| 151 |
| 152 return iter->second; |
| 153 } |
| 154 |
| 146 void RenderFrameHostManager::SetPendingWebUI(const NavigationEntryImpl& entry) { | 155 void RenderFrameHostManager::SetPendingWebUI(const NavigationEntryImpl& entry) { |
| 147 pending_web_ui_.reset( | 156 pending_web_ui_.reset( |
| 148 delegate_->CreateWebUIForRenderManager(entry.GetURL())); | 157 delegate_->CreateWebUIForRenderManager(entry.GetURL())); |
| 149 pending_and_current_web_ui_.reset(); | 158 pending_and_current_web_ui_.reset(); |
| 150 | 159 |
| 151 // If we have assigned (zero or more) bindings to this NavigationEntry in the | 160 // If we have assigned (zero or more) bindings to this NavigationEntry in the |
| 152 // past, make sure we're not granting it different bindings than it had | 161 // past, make sure we're not granting it different bindings than it had |
| 153 // before. If so, note it and don't give it any bindings, to avoid a | 162 // before. If so, note it and don't give it any bindings, to avoid a |
| 154 // potential privilege escalation. | 163 // potential privilege escalation. |
| 155 if (pending_web_ui_.get() && | 164 if (pending_web_ui_.get() && |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 // it out. This must be done before canceling any current dialog, in case | 498 // it out. This must be done before canceling any current dialog, in case |
| 490 // there is a loop creating additional dialogs. | 499 // there is a loop creating additional dialogs. |
| 491 // TODO(creis): Handle modal dialogs in subframe processes. | 500 // TODO(creis): Handle modal dialogs in subframe processes. |
| 492 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); | 501 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); |
| 493 | 502 |
| 494 // Now close any modal dialogs that would prevent us from swapping out. This | 503 // Now close any modal dialogs that would prevent us from swapping out. This |
| 495 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is | 504 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
| 496 // no longer on the stack when we send the SwapOut message. | 505 // no longer on the stack when we send the SwapOut message. |
| 497 delegate_->CancelModalDialogsForRenderManager(); | 506 delegate_->CancelModalDialogsForRenderManager(); |
| 498 | 507 |
| 499 if (!frame_tree_node_->IsMainFrame()) { | |
| 500 // The RenderFrameHost being swapped out becomes the proxy for this | |
| 501 // frame in its parent's process. CrossProcessFrameConnector | |
| 502 // initialization only needs to happen on an initial cross-process | |
| 503 // navigation, when the RenderFrame leaves the same process as its parent. | |
| 504 // The same CrossProcessFrameConnector is used for subsequent cross- | |
| 505 // process navigations, but it will be destroyed if the Frame is | |
| 506 // navigated back to the same site instance as its parent. | |
| 507 // 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_) { | |
| 512 cross_process_frame_connector_ = | |
| 513 new CrossProcessFrameConnector(render_frame_host_.get()); | |
| 514 } | |
| 515 } | |
| 516 | |
| 517 // Create the RenderFrameProxyHost that will replace the | 508 // Create the RenderFrameProxyHost that will replace the |
| 518 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted | 509 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted |
| 519 // from the map and not leaked. | 510 // from the map and not leaked. |
| 520 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( | 511 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( |
| 521 render_frame_host_->GetSiteInstance()->GetId()); | 512 render_frame_host_->GetSiteInstance()->GetId()); |
| 522 if (iter != proxy_hosts_.end()) { | 513 if (iter != proxy_hosts_.end()) { |
| 523 delete iter->second; | 514 delete iter->second; |
| 524 proxy_hosts_.erase(iter); | 515 proxy_hosts_.erase(iter); |
| 525 } | 516 } |
| 526 | 517 |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 | 905 |
| 915 // We are creating a pending or swapped out RFH here. We should never create | 906 // We are creating a pending or swapped out RFH here. We should never create |
| 916 // it in the same SiteInstance as our current RFH. | 907 // it in the same SiteInstance as our current RFH. |
| 917 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 908 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 918 | 909 |
| 919 // Check if we've already created an RFH for this SiteInstance. If so, try | 910 // Check if we've already created an RFH for this SiteInstance. If so, try |
| 920 // to re-use the existing one, which has already been initialized. We'll | 911 // to re-use the existing one, which has already been initialized. We'll |
| 921 // remove it from the list of swapped out hosts if it commits. | 912 // remove it from the list of swapped out hosts if it commits. |
| 922 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 913 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 923 | 914 |
| 924 FrameTreeNode* parent_node = frame_tree_node_->parent(); | |
| 925 | |
| 926 if (proxy) { | 915 if (proxy) { |
| 927 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); | 916 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); |
| 928 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 917 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
| 929 // Prevent the process from exiting while we're trying to use it. | 918 // Prevent the process from exiting while we're trying to use it. |
| 930 if (!swapped_out) { | 919 if (!swapped_out) { |
| 931 new_render_frame_host = proxy->PassFrameHostOwnership(); | 920 new_render_frame_host = proxy->PassFrameHostOwnership(); |
| 932 new_render_frame_host->GetProcess()->AddPendingView(); | 921 new_render_frame_host->GetProcess()->AddPendingView(); |
| 933 | 922 |
| 934 proxy_hosts_.erase(instance->GetId()); | 923 proxy_hosts_.erase(instance->GetId()); |
| 935 delete proxy; | 924 delete proxy; |
| 936 | 925 |
| 937 // When a new render view is created by the renderer, the new WebContents | 926 // When a new render view is created by the renderer, the new WebContents |
| 938 // gets a RenderViewHost in the SiteInstance of its opener WebContents. | 927 // gets a RenderViewHost in the SiteInstance of its opener WebContents. |
| 939 // If not used in the first navigation, this RVH is swapped out and is not | 928 // If not used in the first navigation, this RVH is swapped out and is not |
| 940 // granted bindings, so we may need to grant them when swapping it in. | 929 // granted bindings, so we may need to grant them when swapping it in. |
| 941 if (pending_web_ui() && | 930 if (pending_web_ui() && |
| 942 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | 931 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { |
| 943 int required_bindings = pending_web_ui()->GetBindings(); | 932 int required_bindings = pending_web_ui()->GetBindings(); |
| 944 RenderViewHost* rvh = new_render_frame_host->render_view_host(); | 933 RenderViewHost* rvh = new_render_frame_host->render_view_host(); |
| 945 if ((rvh->GetEnabledBindings() & required_bindings) != | 934 if ((rvh->GetEnabledBindings() & required_bindings) != |
| 946 required_bindings) { | 935 required_bindings) { |
| 947 rvh->AllowBindings(required_bindings); | 936 rvh->AllowBindings(required_bindings); |
| 948 } | 937 } |
| 949 } | 938 } |
| 950 } else { | |
| 951 // Detect if this is a cross-process child frame that is navigating | |
| 952 // back to the same SiteInstance as its parent. | |
| 953 if (parent_node && cross_process_frame_connector_ && | |
| 954 render_frame_host_->GetSiteInstance() == parent_node-> | |
| 955 render_manager()->current_frame_host()->GetSiteInstance()) { | |
| 956 delete cross_process_frame_connector_; | |
| 957 cross_process_frame_connector_ = NULL; | |
| 958 } | |
| 959 } | 939 } |
| 960 } else { | 940 } else { |
| 961 // Create a new RenderFrameHost if we don't find an existing one. | 941 // Create a new RenderFrameHost if we don't find an existing one. |
| 962 new_render_frame_host = CreateRenderFrameHost( | 942 new_render_frame_host = CreateRenderFrameHost( |
| 963 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); | 943 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); |
| 964 RenderViewHostImpl* render_view_host = | 944 RenderViewHostImpl* render_view_host = |
| 965 new_render_frame_host->render_view_host(); | 945 new_render_frame_host->render_view_host(); |
| 966 int proxy_routing_id = MSG_ROUTING_NONE; | 946 int proxy_routing_id = MSG_ROUTING_NONE; |
| 967 | 947 |
| 968 // Prevent the process from exiting while we're trying to navigate in it. | 948 // Prevent the process from exiting while we're trying to navigate in it. |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 // this RFH was the last active one in the SiteInstance. Now that we | 1163 // this RFH was the last active one in the SiteInstance. Now that we |
| 1184 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs | 1164 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
| 1185 // in this SiteInstance. | 1165 // in this SiteInstance. |
| 1186 if (!active_view_count) { | 1166 if (!active_view_count) { |
| 1187 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1167 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
| 1188 } else { | 1168 } else { |
| 1189 // If this is a subframe, it should have a CrossProcessFrameConnector | 1169 // If this is a subframe, it should have a CrossProcessFrameConnector |
| 1190 // created already and we just need to link it to the proper view in the | 1170 // created already and we just need to link it to the proper view in the |
| 1191 // new process. | 1171 // new process. |
| 1192 if (!is_main_frame) { | 1172 if (!is_main_frame) { |
| 1193 RenderWidgetHostView* rwhv = | 1173 RenderFrameProxyHost* proxy = GetProxyToParent(); |
| 1194 render_frame_host_->render_view_host()->GetView(); | 1174 if (proxy) { |
| 1195 RenderWidgetHostViewChildFrame* rwhv_child = | 1175 proxy->SetChildRWHView( |
| 1196 static_cast<RenderWidgetHostViewChildFrame*>(rwhv); | 1176 render_frame_host_->render_view_host()->GetView()); |
| 1197 cross_process_frame_connector_->set_view(rwhv_child); | 1177 } |
| 1198 } | 1178 } |
| 1199 } | 1179 } |
| 1200 } | 1180 } |
| 1201 } | 1181 } |
| 1202 | 1182 |
| 1203 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1183 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
| 1204 int32 site_instance_id) { | 1184 int32 site_instance_id) { |
| 1205 // First remove any swapped out RFH for this SiteInstance from our own list. | 1185 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1206 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1186 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1207 | 1187 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 SiteInstance* instance) const { | 1462 SiteInstance* instance) const { |
| 1483 RenderFrameProxyHostMap::const_iterator iter = | 1463 RenderFrameProxyHostMap::const_iterator iter = |
| 1484 proxy_hosts_.find(instance->GetId()); | 1464 proxy_hosts_.find(instance->GetId()); |
| 1485 if (iter != proxy_hosts_.end()) | 1465 if (iter != proxy_hosts_.end()) |
| 1486 return iter->second; | 1466 return iter->second; |
| 1487 | 1467 |
| 1488 return NULL; | 1468 return NULL; |
| 1489 } | 1469 } |
| 1490 | 1470 |
| 1491 } // namespace content | 1471 } // namespace content |
| OLD | NEW |