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::ProxyToParent() { | |
140 if (frame_tree_node_->IsMainFrame()) { | |
141 LOG(ERROR) << "RFHM::ProxyToParent[" << this << "]: main frame"; | |
142 return NULL; | |
143 } | |
144 | |
145 RenderFrameProxyHostMap::iterator iter = | |
146 proxy_hosts_.find( | |
147 frame_tree_node_->parent()->render_manager()->current_frame_host() | |
148 ->GetSiteInstance()->GetId()); | |
149 if (iter == proxy_hosts_.end()) { | |
150 LOG(ERROR) << "RFHM::ProxyToParent[" << this << "]:" | |
151 << " proxy for " << | |
152 frame_tree_node_->parent()->render_manager()->current_frame_host() | |
153 ->GetSiteInstance()->GetSiteURL() | |
154 << " not found"; | |
155 return NULL; | |
156 } | |
157 | |
158 LOG(ERROR) << "RFHM::ProxyToParent[" << this << "]:" | |
159 << " proxy:" << iter->second | |
160 << ", site:" << iter->second->GetSiteInstance()->GetSiteURL(); | |
161 return iter->second; | |
162 } | |
163 | |
146 void RenderFrameHostManager::SetPendingWebUI(const NavigationEntryImpl& entry) { | 164 void RenderFrameHostManager::SetPendingWebUI(const NavigationEntryImpl& entry) { |
147 pending_web_ui_.reset( | 165 pending_web_ui_.reset( |
148 delegate_->CreateWebUIForRenderManager(entry.GetURL())); | 166 delegate_->CreateWebUIForRenderManager(entry.GetURL())); |
149 pending_and_current_web_ui_.reset(); | 167 pending_and_current_web_ui_.reset(); |
150 | 168 |
151 // If we have assigned (zero or more) bindings to this NavigationEntry in the | 169 // 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 | 170 // 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 | 171 // before. If so, note it and don't give it any bindings, to avoid a |
154 // potential privilege escalation. | 172 // potential privilege escalation. |
155 if (pending_web_ui_.get() && | 173 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 | 507 // it out. This must be done before canceling any current dialog, in case |
490 // there is a loop creating additional dialogs. | 508 // there is a loop creating additional dialogs. |
491 // TODO(creis): Handle modal dialogs in subframe processes. | 509 // TODO(creis): Handle modal dialogs in subframe processes. |
492 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); | 510 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); |
493 | 511 |
494 // Now close any modal dialogs that would prevent us from swapping out. This | 512 // 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 | 513 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
496 // no longer on the stack when we send the SwapOut message. | 514 // no longer on the stack when we send the SwapOut message. |
497 delegate_->CancelModalDialogsForRenderManager(); | 515 delegate_->CancelModalDialogsForRenderManager(); |
498 | 516 |
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 | 517 // Create the RenderFrameProxyHost that will replace the |
518 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted | 518 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted |
519 // from the map and not leaked. | 519 // from the map and not leaked. |
520 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( | 520 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( |
521 render_frame_host_->GetSiteInstance()->GetId()); | 521 render_frame_host_->GetSiteInstance()->GetId()); |
522 if (iter != proxy_hosts_.end()) { | 522 if (iter != proxy_hosts_.end()) { |
523 delete iter->second; | 523 delete iter->second; |
524 proxy_hosts_.erase(iter); | 524 proxy_hosts_.erase(iter); |
525 } | 525 } |
526 | 526 |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
914 | 914 |
915 // We are creating a pending or swapped out RFH here. We should never create | 915 // We are creating a pending or swapped out RFH here. We should never create |
916 // it in the same SiteInstance as our current RFH. | 916 // it in the same SiteInstance as our current RFH. |
917 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 917 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
918 | 918 |
919 // Check if we've already created an RFH for this SiteInstance. If so, try | 919 // 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 | 920 // 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. | 921 // remove it from the list of swapped out hosts if it commits. |
922 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 922 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
923 | 923 |
924 FrameTreeNode* parent_node = frame_tree_node_->parent(); | |
925 | |
926 if (proxy) { | 924 if (proxy) { |
927 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); | 925 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); |
928 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 926 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
929 // Prevent the process from exiting while we're trying to use it. | 927 // Prevent the process from exiting while we're trying to use it. |
930 if (!swapped_out) { | 928 if (!swapped_out) { |
931 new_render_frame_host = proxy->PassFrameHostOwnership(); | 929 new_render_frame_host = proxy->PassFrameHostOwnership(); |
932 new_render_frame_host->GetProcess()->AddPendingView(); | 930 new_render_frame_host->GetProcess()->AddPendingView(); |
933 | 931 |
934 proxy_hosts_.erase(instance->GetId()); | 932 proxy_hosts_.erase(instance->GetId()); |
935 delete proxy; | 933 delete proxy; |
936 | 934 |
937 // When a new render view is created by the renderer, the new WebContents | 935 // When a new render view is created by the renderer, the new WebContents |
938 // gets a RenderViewHost in the SiteInstance of its opener WebContents. | 936 // 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 | 937 // 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. | 938 // granted bindings, so we may need to grant them when swapping it in. |
941 if (pending_web_ui() && | 939 if (pending_web_ui() && |
942 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | 940 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { |
943 int required_bindings = pending_web_ui()->GetBindings(); | 941 int required_bindings = pending_web_ui()->GetBindings(); |
944 RenderViewHost* rvh = new_render_frame_host->render_view_host(); | 942 RenderViewHost* rvh = new_render_frame_host->render_view_host(); |
945 if ((rvh->GetEnabledBindings() & required_bindings) != | 943 if ((rvh->GetEnabledBindings() & required_bindings) != |
946 required_bindings) { | 944 required_bindings) { |
947 rvh->AllowBindings(required_bindings); | 945 rvh->AllowBindings(required_bindings); |
948 } | 946 } |
949 } | 947 } |
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 } | 948 } |
960 } else { | 949 } else { |
961 // Create a new RenderFrameHost if we don't find an existing one. | 950 // Create a new RenderFrameHost if we don't find an existing one. |
962 new_render_frame_host = CreateRenderFrameHost( | 951 new_render_frame_host = CreateRenderFrameHost( |
963 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); | 952 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); |
964 RenderViewHostImpl* render_view_host = | 953 RenderViewHostImpl* render_view_host = |
965 new_render_frame_host->render_view_host(); | 954 new_render_frame_host->render_view_host(); |
966 int proxy_routing_id = MSG_ROUTING_NONE; | 955 int proxy_routing_id = MSG_ROUTING_NONE; |
967 | 956 |
968 // Prevent the process from exiting while we're trying to navigate in it. | 957 // 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 | 1172 // 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 | 1173 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
1185 // in this SiteInstance. | 1174 // in this SiteInstance. |
1186 if (!active_view_count) { | 1175 if (!active_view_count) { |
1187 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1176 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
1188 } else { | 1177 } else { |
1189 // If this is a subframe, it should have a CrossProcessFrameConnector | 1178 // 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 | 1179 // created already and we just need to link it to the proper view in the |
1191 // new process. | 1180 // new process. |
1192 if (!is_main_frame) { | 1181 if (!is_main_frame) { |
1193 RenderWidgetHostView* rwhv = | 1182 RenderFrameProxyHost* proxy = ProxyToParent(); |
1194 render_frame_host_->render_view_host()->GetView(); | 1183 if (proxy) |
1195 RenderWidgetHostViewChildFrame* rwhv_child = | 1184 proxy->SetView(render_frame_host_->render_view_host()->GetView()); |
kenrb
2014/06/06 16:10:56
Is this the wrong view being set? We are trying to
kenrb
2014/06/06 18:06:02
Ah, never mind. This should be happening in the ch
| |
1196 static_cast<RenderWidgetHostViewChildFrame*>(rwhv); | |
1197 cross_process_frame_connector_->set_view(rwhv_child); | |
1198 } | 1185 } |
1199 } | 1186 } |
1200 } | 1187 } |
1201 } | 1188 } |
1202 | 1189 |
1203 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1190 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
1204 int32 site_instance_id) { | 1191 int32 site_instance_id) { |
1205 // First remove any swapped out RFH for this SiteInstance from our own list. | 1192 // First remove any swapped out RFH for this SiteInstance from our own list. |
1206 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1193 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
1207 | 1194 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1482 SiteInstance* instance) const { | 1469 SiteInstance* instance) const { |
1483 RenderFrameProxyHostMap::const_iterator iter = | 1470 RenderFrameProxyHostMap::const_iterator iter = |
1484 proxy_hosts_.find(instance->GetId()); | 1471 proxy_hosts_.find(instance->GetId()); |
1485 if (iter != proxy_hosts_.end()) | 1472 if (iter != proxy_hosts_.end()) |
1486 return iter->second; | 1473 return iter->second; |
1487 | 1474 |
1488 return NULL; | 1475 return NULL; |
1489 } | 1476 } |
1490 | 1477 |
1491 } // namespace content | 1478 } // namespace content |
OLD | NEW |