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 |