| 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" |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 // from the map and not leaked. | 531 // from the map and not leaked. |
| 532 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( | 532 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( |
| 533 render_frame_host_->GetSiteInstance()->GetId()); | 533 render_frame_host_->GetSiteInstance()->GetId()); |
| 534 if (iter != proxy_hosts_.end()) { | 534 if (iter != proxy_hosts_.end()) { |
| 535 delete iter->second; | 535 delete iter->second; |
| 536 proxy_hosts_.erase(iter); | 536 proxy_hosts_.erase(iter); |
| 537 } | 537 } |
| 538 | 538 |
| 539 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | 539 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
| 540 render_frame_host_->GetSiteInstance(), frame_tree_node_); | 540 render_frame_host_->GetSiteInstance(), frame_tree_node_); |
| 541 std::pair<RenderFrameProxyHostMap::iterator, bool> result = | 541 proxy_hosts_[render_frame_host_->GetSiteInstance()->GetId()] = proxy; |
| 542 proxy_hosts_.insert(std::make_pair( | |
| 543 render_frame_host_->GetSiteInstance()->GetId(), proxy)); | |
| 544 CHECK(result.second) << "Inserting a duplicate item."; | |
| 545 | 542 |
| 546 // Tell the old frame it is being swapped out. This will fire the unload | 543 // Tell the old frame it is being swapped out. This will fire the unload |
| 547 // handler in the background (without firing the beforeunload handler a second | 544 // handler in the background (without firing the beforeunload handler a second |
| 548 // time). When the navigation completes, we will send a message to the | 545 // time). When the navigation completes, we will send a message to the |
| 549 // ResourceDispatcherHost, allowing the pending RVH's response to resume. | 546 // ResourceDispatcherHost, allowing the pending RVH's response to resume. |
| 550 render_frame_host_->SwapOut(proxy); | 547 render_frame_host_->SwapOut(proxy); |
| 551 | 548 |
| 552 // ResourceDispatcherHost has told us to run the onunload handler, which | 549 // ResourceDispatcherHost has told us to run the onunload handler, which |
| 553 // means it is not a download or unsafe page, and we are going to perform the | 550 // means it is not a download or unsafe page, and we are going to perform the |
| 554 // navigation. Thus, we no longer need to remember that the RenderFrameHost | 551 // navigation. Thus, we no longer need to remember that the RenderFrameHost |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 | 902 |
| 906 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 903 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( |
| 907 SiteInstance* site_instance, | 904 SiteInstance* site_instance, |
| 908 int view_routing_id, | 905 int view_routing_id, |
| 909 int frame_routing_id, | 906 int frame_routing_id, |
| 910 bool swapped_out, | 907 bool swapped_out, |
| 911 bool hidden) { | 908 bool hidden) { |
| 912 if (frame_routing_id == MSG_ROUTING_NONE) | 909 if (frame_routing_id == MSG_ROUTING_NONE) |
| 913 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 910 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
| 914 | 911 |
| 915 // Create a RVH for the new frame or find an existing one. | 912 // Create a RVH for main frames, or find the existing one for subframes. |
| 916 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 913 FrameTree* frame_tree = frame_tree_node_->frame_tree(); |
| 917 RenderViewHostImpl* render_view_host = | 914 RenderViewHostImpl* render_view_host = NULL; |
| 918 frame_tree->GetRenderViewHost(site_instance); | 915 if (frame_tree_node_->IsMainFrame()) { |
| 919 if (!render_view_host) { | 916 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( |
| 920 render_view_host = frame_tree->CreateRenderViewHost( | |
| 921 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); | 917 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); |
| 918 } else { |
| 919 render_view_host = frame_tree->GetRenderViewHostForSubFrame(site_instance); |
| 920 |
| 921 // If we haven't found a RVH for a subframe RFH, it's because we currently |
| 922 // do not create top-level RFHs for pending subframe navigations. Create |
| 923 // the RVH here for now. |
| 924 // TODO(creis): Mirror the frame tree so this check isn't necessary. |
| 925 if (!render_view_host) { |
| 926 render_view_host = frame_tree->CreateRenderViewHostForMainFrame( |
| 927 site_instance, view_routing_id, frame_routing_id, swapped_out, |
| 928 hidden); |
| 929 } |
| 922 } | 930 } |
| 923 | 931 |
| 924 // TODO(creis): Pass hidden to RFH. | 932 // TODO(creis): Pass hidden to RFH. |
| 925 scoped_ptr<RenderFrameHostImpl> render_frame_host = | 933 scoped_ptr<RenderFrameHostImpl> render_frame_host = |
| 926 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host, | 934 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host, |
| 927 render_frame_delegate_, | 935 render_frame_delegate_, |
| 928 frame_tree, | 936 frame_tree, |
| 929 frame_tree_node_, | 937 frame_tree_node_, |
| 930 frame_routing_id, | 938 frame_routing_id, |
| 931 swapped_out).release()); | 939 swapped_out).release()); |
| 932 return render_frame_host.Pass(); | 940 return render_frame_host.Pass(); |
| 933 } | 941 } |
| 934 | 942 |
| 935 int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 943 int RenderFrameHostManager::CreateRenderFrame( |
| 936 int opener_route_id, | 944 SiteInstance* instance, |
| 937 bool swapped_out, | 945 int opener_route_id, |
| 938 bool for_main_frame_navigation, | 946 bool swapped_out, |
| 939 bool hidden) { | 947 bool hidden) { |
| 940 CHECK(instance); | 948 CHECK(instance); |
| 941 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. | 949 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. |
| 942 | 950 |
| 943 // TODO(nasko): Remove the following CHECK once cross-site navigation no | |
| 944 // longer relies on swapped out RFH for the top-level frame. | |
| 945 if (!frame_tree_node_->IsMainFrame()) { | |
| 946 CHECK(!swapped_out); | |
| 947 } | |
| 948 | |
| 949 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | 951 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; |
| 950 RenderFrameHostImpl* frame_to_announce = NULL; | 952 RenderFrameHostImpl* frame_to_announce = NULL; |
| 951 int routing_id = MSG_ROUTING_NONE; | 953 int routing_id = MSG_ROUTING_NONE; |
| 952 | 954 |
| 953 // We are creating a pending or swapped out RFH here. We should never create | 955 // We are creating a pending or swapped out RFH here. We should never create |
| 954 // it in the same SiteInstance as our current RFH. | 956 // it in the same SiteInstance as our current RFH. |
| 955 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 957 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 956 | 958 |
| 957 // Check if we've already created an RFH for this SiteInstance. If so, try | 959 // Check if we've already created an RFH for this SiteInstance. If so, try |
| 958 // to re-use the existing one, which has already been initialized. We'll | 960 // to re-use the existing one, which has already been initialized. We'll |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 if (!swapped_out) { | 999 if (!swapped_out) { |
| 998 new_render_frame_host->GetProcess()->AddPendingView(); | 1000 new_render_frame_host->GetProcess()->AddPendingView(); |
| 999 } else { | 1001 } else { |
| 1000 proxy = new RenderFrameProxyHost( | 1002 proxy = new RenderFrameProxyHost( |
| 1001 new_render_frame_host->GetSiteInstance(), frame_tree_node_); | 1003 new_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 1002 proxy_hosts_[instance->GetId()] = proxy; | 1004 proxy_hosts_[instance->GetId()] = proxy; |
| 1003 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); | 1005 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); |
| 1004 proxy_routing_id = proxy->GetRoutingID(); | 1006 proxy_routing_id = proxy->GetRoutingID(); |
| 1005 } | 1007 } |
| 1006 | 1008 |
| 1007 bool success = InitRenderView(render_view_host, | 1009 bool success = InitRenderView( |
| 1008 opener_route_id, | 1010 render_view_host, opener_route_id, proxy_routing_id, |
| 1009 proxy_routing_id, | 1011 frame_tree_node_->IsMainFrame()); |
| 1010 for_main_frame_navigation); | 1012 if (success && frame_tree_node_->IsMainFrame()) { |
| 1011 if (success) { | 1013 // Don't show the main frame's view until we get a DidNavigate from it. |
| 1012 if (frame_tree_node_->IsMainFrame()) { | 1014 render_view_host->GetView()->Hide(); |
| 1013 // Don't show the main frame's view until we get a DidNavigate from it. | |
| 1014 render_view_host->GetView()->Hide(); | |
| 1015 } else if (!swapped_out) { | |
| 1016 // Init the RFH, so a RenderFrame is created in the renderer. | |
| 1017 DCHECK(new_render_frame_host.get()); | |
| 1018 success = InitRenderFrame(new_render_frame_host.get()); | |
| 1019 } | |
| 1020 if (swapped_out) { | |
| 1021 proxy_hosts_[instance->GetId()]->InitRenderFrameProxy(); | |
| 1022 } | |
| 1023 } else if (!swapped_out && pending_render_frame_host_) { | 1015 } else if (!swapped_out && pending_render_frame_host_) { |
| 1024 CancelPending(); | 1016 CancelPending(); |
| 1025 } | 1017 } |
| 1026 routing_id = render_view_host->GetRoutingID(); | 1018 routing_id = render_view_host->GetRoutingID(); |
| 1027 frame_to_announce = new_render_frame_host.get(); | 1019 frame_to_announce = new_render_frame_host.get(); |
| 1028 } | 1020 } |
| 1029 | 1021 |
| 1030 // Use this as our new pending RFH if it isn't swapped out. | 1022 // Use this as our new pending RFH if it isn't swapped out. |
| 1031 if (!swapped_out) | 1023 if (!swapped_out) |
| 1032 pending_render_frame_host_ = new_render_frame_host.Pass(); | 1024 pending_render_frame_host_ = new_render_frame_host.Pass(); |
| 1033 | 1025 |
| 1034 // If a brand new RFH was created, announce it to observers. | 1026 // If a brand new RFH was created, announce it to observers. |
| 1035 if (frame_to_announce) | 1027 if (frame_to_announce) |
| 1036 render_frame_delegate_->RenderFrameCreated(frame_to_announce); | 1028 render_frame_delegate_->RenderFrameCreated(frame_to_announce); |
| 1037 | 1029 |
| 1038 return routing_id; | 1030 return routing_id; |
| 1039 } | 1031 } |
| 1040 | 1032 |
| 1041 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | |
| 1042 // A RenderFrameProxyHost should never be created in the same SiteInstance as | |
| 1043 // the current RFH. | |
| 1044 CHECK(instance); | |
| 1045 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); | |
| 1046 | |
| 1047 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | |
| 1048 if (proxy) | |
| 1049 return proxy->GetRoutingID(); | |
| 1050 | |
| 1051 proxy = new RenderFrameProxyHost(instance, frame_tree_node_); | |
| 1052 proxy_hosts_[instance->GetId()] = proxy; | |
| 1053 proxy->InitRenderFrameProxy(); | |
| 1054 return proxy->GetRoutingID(); | |
| 1055 } | |
| 1056 | |
| 1057 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, | 1033 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, |
| 1058 int opener_route_id, | 1034 int opener_route_id, |
| 1059 int proxy_routing_id, | 1035 int proxy_routing_id, |
| 1060 bool for_main_frame_navigation) { | 1036 bool for_main_frame) { |
| 1061 // We may have initialized this RenderViewHost for another RenderFrameHost. | 1037 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 1062 if (render_view_host->IsRenderViewLive()) | 1038 if (render_view_host->IsRenderViewLive()) |
| 1063 return true; | 1039 return true; |
| 1064 | 1040 |
| 1065 // If the pending navigation is to a WebUI and the RenderView is not in a | 1041 // If the pending navigation is to a WebUI and the RenderView is not in a |
| 1066 // guest process, tell the RenderViewHost about any bindings it will need | 1042 // guest process, tell the RenderViewHost about any bindings it will need |
| 1067 // enabled. | 1043 // enabled. |
| 1068 if (pending_web_ui() && !render_view_host->GetProcess()->IsIsolatedGuest()) { | 1044 if (pending_web_ui() && !render_view_host->GetProcess()->IsIsolatedGuest()) { |
| 1069 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 1045 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
| 1070 } else { | 1046 } else { |
| 1071 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 1047 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
| 1072 // process unless it's swapped out. | 1048 // process unless it's swapped out. |
| 1073 RenderViewHostImpl* rvh_impl = | 1049 RenderViewHostImpl* rvh_impl = |
| 1074 static_cast<RenderViewHostImpl*>(render_view_host); | 1050 static_cast<RenderViewHostImpl*>(render_view_host); |
| 1075 if (!rvh_impl->IsSwappedOut()) { | 1051 if (!rvh_impl->IsSwappedOut()) { |
| 1076 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1052 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
| 1077 render_view_host->GetProcess()->GetID())); | 1053 render_view_host->GetProcess()->GetID())); |
| 1078 } | 1054 } |
| 1079 } | 1055 } |
| 1080 | 1056 |
| 1081 return delegate_->CreateRenderViewForRenderManager( | 1057 return delegate_->CreateRenderViewForRenderManager( |
| 1082 render_view_host, | 1058 render_view_host, opener_route_id, proxy_routing_id, for_main_frame); |
| 1083 opener_route_id, | |
| 1084 proxy_routing_id, | |
| 1085 for_main_frame_navigation); | |
| 1086 } | |
| 1087 | |
| 1088 bool RenderFrameHostManager::InitRenderFrame( | |
| 1089 RenderFrameHost* render_frame_host) { | |
| 1090 RenderFrameHostImpl* rfh = | |
| 1091 static_cast<RenderFrameHostImpl*>(render_frame_host); | |
| 1092 if (rfh->IsRenderFrameLive()) | |
| 1093 return true; | |
| 1094 | |
| 1095 int parent_routing_id = MSG_ROUTING_NONE; | |
| 1096 if (frame_tree_node_->parent()) { | |
| 1097 parent_routing_id = frame_tree_node_->parent()->render_manager()-> | |
| 1098 GetRoutingIdForSiteInstance(render_frame_host->GetSiteInstance()); | |
| 1099 CHECK_NE(parent_routing_id, MSG_ROUTING_NONE); | |
| 1100 } | |
| 1101 return delegate_->CreateRenderFrameForRenderManager(render_frame_host, | |
| 1102 parent_routing_id); | |
| 1103 } | |
| 1104 | |
| 1105 int RenderFrameHostManager::GetRoutingIdForSiteInstance( | |
| 1106 SiteInstance* site_instance) { | |
| 1107 if (render_frame_host_->GetSiteInstance() == site_instance) | |
| 1108 return render_frame_host_->GetRoutingID(); | |
| 1109 | |
| 1110 RenderFrameProxyHostMap::iterator iter = | |
| 1111 proxy_hosts_.find(site_instance->GetId()); | |
| 1112 if (iter != proxy_hosts_.end()) | |
| 1113 return iter->second->GetRoutingID(); | |
| 1114 | |
| 1115 return MSG_ROUTING_NONE; | |
| 1116 } | 1059 } |
| 1117 | 1060 |
| 1118 void RenderFrameHostManager::CommitPending() { | 1061 void RenderFrameHostManager::CommitPending() { |
| 1119 // First check whether we're going to want to focus the location bar after | 1062 // First check whether we're going to want to focus the location bar after |
| 1120 // this commit. We do this now because the navigation hasn't formally | 1063 // this commit. We do this now because the navigation hasn't formally |
| 1121 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1064 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 1122 // this triggers won't be able to figure out what's going on. | 1065 // this triggers won't be able to figure out what's going on. |
| 1123 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1066 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 1124 | 1067 |
| 1125 // We expect SwapOutOldPage to have canceled any modal dialogs and told the | 1068 // We expect SwapOutOldPage to have canceled any modal dialogs and told the |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 // TODO(creis): Swap out the subframe in --site-per-process. | 1168 // TODO(creis): Swap out the subframe in --site-per-process. |
| 1226 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 1169 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) |
| 1227 DCHECK(old_render_frame_host->is_swapped_out() || | 1170 DCHECK(old_render_frame_host->is_swapped_out() || |
| 1228 !RenderViewHostImpl::IsRVHStateActive( | 1171 !RenderViewHostImpl::IsRVHStateActive( |
| 1229 old_render_frame_host->render_view_host()->rvh_state())); | 1172 old_render_frame_host->render_view_host()->rvh_state())); |
| 1230 | 1173 |
| 1231 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, | 1174 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, |
| 1232 // the RenderFrameHost should be put in the map of RenderFrameHosts pending | 1175 // the RenderFrameHost should be put in the map of RenderFrameHosts pending |
| 1233 // shutdown. Otherwise, it is stored in the map of proxy hosts. | 1176 // shutdown. Otherwise, it is stored in the map of proxy hosts. |
| 1234 if (old_render_frame_host->render_view_host()->rvh_state() == | 1177 if (old_render_frame_host->render_view_host()->rvh_state() == |
| 1235 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { | 1178 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { |
| 1236 // The proxy for this RenderFrameHost is created when sending the | 1179 // The proxy for this RenderFrameHost is created when sending the |
| 1237 // SwapOut message, so check if it already exists and delete it. | 1180 // SwapOut message, so check if it already exists and delete it. |
| 1238 RenderFrameProxyHostMap::iterator iter = | 1181 RenderFrameProxyHostMap::iterator iter = |
| 1239 proxy_hosts_.find(old_site_instance_id); | 1182 proxy_hosts_.find(old_site_instance_id); |
| 1240 if (iter != proxy_hosts_.end()) { | 1183 if (iter != proxy_hosts_.end()) { |
| 1241 delete iter->second; | 1184 delete iter->second; |
| 1242 proxy_hosts_.erase(iter); | 1185 proxy_hosts_.erase(iter); |
| 1243 } | 1186 } |
| 1244 RFHPendingDeleteMap::iterator pending_delete_iter = | 1187 RFHPendingDeleteMap::iterator pending_delete_iter = |
| 1245 pending_delete_hosts_.find(old_site_instance_id); | 1188 pending_delete_hosts_.find(old_site_instance_id); |
| 1246 if (pending_delete_iter == pending_delete_hosts_.end() || | 1189 if (pending_delete_iter == pending_delete_hosts_.end() || |
| 1247 pending_delete_iter->second.get() != old_render_frame_host) { | 1190 pending_delete_iter->second.get() != old_render_frame_host) { |
| 1248 pending_delete_hosts_[old_site_instance_id] = | 1191 pending_delete_hosts_[old_site_instance_id] = |
| 1249 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); | 1192 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); |
| 1250 } | 1193 } |
| 1251 } else { | 1194 } else { |
| 1252 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) == | |
| 1253 proxy_hosts_.end()); | |
| 1254 | |
| 1255 // Capture the active view count on the old RFH SiteInstance, since the | 1195 // Capture the active view count on the old RFH SiteInstance, since the |
| 1256 // ownership might be passed into the proxy and the pointer will be | 1196 // ownership will be passed into the proxy and the pointer will be invalid. |
| 1257 // invalid. | |
| 1258 int active_view_count = | 1197 int active_view_count = |
| 1259 static_cast<SiteInstanceImpl*>(old_render_frame_host->GetSiteInstance()) | 1198 static_cast<SiteInstanceImpl*>(old_render_frame_host->GetSiteInstance()) |
| 1260 ->active_view_count(); | 1199 ->active_view_count(); |
| 1261 | 1200 |
| 1262 if (is_main_frame) { | 1201 RenderFrameProxyHostMap::iterator iter = |
| 1263 RenderFrameProxyHostMap::iterator iter = | 1202 proxy_hosts_.find(old_site_instance_id); |
| 1264 proxy_hosts_.find(old_site_instance_id); | 1203 CHECK(iter != proxy_hosts_.end()); |
| 1265 CHECK(iter != proxy_hosts_.end()); | 1204 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 1266 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); | |
| 1267 } | |
| 1268 | 1205 |
| 1269 // If there are no active views in this SiteInstance, it means that | 1206 // If there are no active views in this SiteInstance, it means that |
| 1270 // this RFH was the last active one in the SiteInstance. Now that we | 1207 // this RFH was the last active one in the SiteInstance. Now that we |
| 1271 // know that all RFHs are swapped out, we can delete all the RFPHs and | 1208 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
| 1272 // RVHs in this SiteInstance. | 1209 // in this SiteInstance. |
| 1273 if (!active_view_count) { | 1210 if (!active_view_count) { |
| 1274 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); | 1211 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
| 1275 } else { | 1212 } else { |
| 1276 // If this is a subframe, it should have a CrossProcessFrameConnector | 1213 // If this is a subframe, it should have a CrossProcessFrameConnector |
| 1277 // created already and we just need to link it to the proper view in the | 1214 // created already and we just need to link it to the proper view in the |
| 1278 // new process. | 1215 // new process. |
| 1279 if (!is_main_frame) { | 1216 if (!is_main_frame) { |
| 1280 RenderFrameProxyHost* proxy = GetProxyToParent(); | 1217 RenderFrameProxyHost* proxy = GetProxyToParent(); |
| 1281 if (proxy) { | 1218 if (proxy) { |
| 1282 proxy->SetChildRWHView( | 1219 proxy->SetChildRWHView( |
| 1283 render_frame_host_->render_view_host()->GetView()); | 1220 render_frame_host_->render_view_host()->GetView()); |
| 1284 } | 1221 } |
| 1285 } | 1222 } |
| 1286 } | 1223 } |
| 1287 } | 1224 } |
| 1288 } | 1225 } |
| 1289 | 1226 |
| 1290 void RenderFrameHostManager::ShutdownRenderFrameProxyHostsInSiteInstance( | 1227 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
| 1291 int32 site_instance_id) { | 1228 int32 site_instance_id) { |
| 1292 // First remove any swapped out RFH for this SiteInstance from our own list. | 1229 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1293 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1230 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1294 | 1231 |
| 1295 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1232 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
| 1296 // in the SiteInstance, then tell their respective FrameTrees to remove all | 1233 // in the SiteInstance, then tell their respective FrameTrees to remove all |
| 1297 // RenderFrameProxyHosts corresponding to them. | 1234 // RenderFrameProxyHosts corresponding to them. |
| 1298 // TODO(creis): Replace this with a RenderFrameHostIterator that protects | 1235 // TODO(creis): Replace this with a RenderFrameHostIterator that protects |
| 1299 // against use-after-frees if a later element is deleted before getting to it. | 1236 // against use-after-frees if a later element is deleted before getting to it. |
| 1300 scoped_ptr<RenderWidgetHostIterator> widgets( | 1237 scoped_ptr<RenderWidgetHostIterator> widgets( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1318 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( | 1255 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( |
| 1319 const NavigationEntryImpl& entry) { | 1256 const NavigationEntryImpl& entry) { |
| 1320 // If we are currently navigating cross-process, we want to get back to normal | 1257 // If we are currently navigating cross-process, we want to get back to normal |
| 1321 // and then navigate as usual. | 1258 // and then navigate as usual. |
| 1322 if (cross_navigation_pending_) { | 1259 if (cross_navigation_pending_) { |
| 1323 if (pending_render_frame_host_) | 1260 if (pending_render_frame_host_) |
| 1324 CancelPending(); | 1261 CancelPending(); |
| 1325 cross_navigation_pending_ = false; | 1262 cross_navigation_pending_ = false; |
| 1326 } | 1263 } |
| 1327 | 1264 |
| 1265 // render_frame_host_'s SiteInstance and new_instance will not be deleted |
| 1266 // before the end of this method, so we don't have to worry about their ref |
| 1267 // counts dropping to zero. |
| 1328 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1268 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 1329 scoped_refptr<SiteInstance> new_instance = current_instance; | 1269 SiteInstance* new_instance = current_instance; |
| 1330 | 1270 |
| 1331 // We do not currently swap processes for navigations in webview tag guests. | 1271 // We do not currently swap processes for navigations in webview tag guests. |
| 1332 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); | 1272 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); |
| 1333 | 1273 |
| 1334 // Determine if we need a new BrowsingInstance for this entry. If true, this | 1274 // Determine if we need a new BrowsingInstance for this entry. If true, this |
| 1335 // implies that it will get a new SiteInstance (and likely process), and that | 1275 // implies that it will get a new SiteInstance (and likely process), and that |
| 1336 // other tabs in the current BrowsingInstance will be unable to script it. | 1276 // other tabs in the current BrowsingInstance will be unable to script it. |
| 1337 // This is used for cases that require a process swap even in the | 1277 // This is used for cases that require a process swap even in the |
| 1338 // process-per-tab model, such as WebUI pages. | 1278 // process-per-tab model, such as WebUI pages. |
| 1339 const NavigationEntry* current_entry = | 1279 const NavigationEntry* current_entry = |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1361 // not have its bindings set appropriately. | 1301 // not have its bindings set appropriately. |
| 1362 SetPendingWebUI(entry); | 1302 SetPendingWebUI(entry); |
| 1363 | 1303 |
| 1364 // Ensure that we have created RFHs for the new RFH's opener chain if | 1304 // Ensure that we have created RFHs for the new RFH's opener chain if |
| 1365 // we are staying in the same BrowsingInstance. This allows the pending RFH | 1305 // we are staying in the same BrowsingInstance. This allows the pending RFH |
| 1366 // to send cross-process script calls to its opener(s). | 1306 // to send cross-process script calls to its opener(s). |
| 1367 int opener_route_id = MSG_ROUTING_NONE; | 1307 int opener_route_id = MSG_ROUTING_NONE; |
| 1368 if (new_instance->IsRelatedSiteInstance(current_instance)) { | 1308 if (new_instance->IsRelatedSiteInstance(current_instance)) { |
| 1369 opener_route_id = | 1309 opener_route_id = |
| 1370 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | 1310 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); |
| 1371 | |
| 1372 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1373 switches::kSitePerProcess)) { | |
| 1374 // Ensure that the frame tree has RenderFrameProxyHosts for the new | |
| 1375 // SiteInstance in all nodes except the current one. | |
| 1376 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | |
| 1377 frame_tree_node_, new_instance); | |
| 1378 } | |
| 1379 } | 1311 } |
| 1380 | 1312 |
| 1381 // Create a non-swapped-out pending RFH with the given opener and navigate | 1313 // Create a non-swapped-out pending RFH with the given opener and navigate |
| 1382 // it. | 1314 // it. |
| 1383 int route_id = CreateRenderFrame(new_instance, | 1315 int route_id = CreateRenderFrame(new_instance, opener_route_id, false, |
| 1384 opener_route_id, | |
| 1385 false, | |
| 1386 frame_tree_node_->IsMainFrame(), | |
| 1387 delegate_->IsHidden()); | 1316 delegate_->IsHidden()); |
| 1388 if (route_id == MSG_ROUTING_NONE) | 1317 if (route_id == MSG_ROUTING_NONE) |
| 1389 return NULL; | 1318 return NULL; |
| 1390 | 1319 |
| 1391 // Check if our current RFH is live before we set up a transition. | 1320 // Check if our current RFH is live before we set up a transition. |
| 1392 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | 1321 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { |
| 1393 if (!cross_navigation_pending_) { | 1322 if (!cross_navigation_pending_) { |
| 1394 // The current RFH is not live. There's no reason to sit around with a | 1323 // The current RFH is not live. There's no reason to sit around with a |
| 1395 // sad tab or a newly created RFH while we wait for the pending RFH to | 1324 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 1396 // navigate. Just switch to the pending RFH now and go back to non | 1325 // navigate. Just switch to the pending RFH now and go back to non |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( | 1430 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( |
| 1502 pending_render_frame_host->GetSiteInstance()); | 1431 pending_render_frame_host->GetSiteInstance()); |
| 1503 if (site_instance->active_view_count() > 1) { | 1432 if (site_instance->active_view_count() > 1) { |
| 1504 // Any currently suspended navigations are no longer needed. | 1433 // Any currently suspended navigations are no longer needed. |
| 1505 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1434 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
| 1506 | 1435 |
| 1507 RenderFrameProxyHost* proxy = | 1436 RenderFrameProxyHost* proxy = |
| 1508 new RenderFrameProxyHost(site_instance, frame_tree_node_); | 1437 new RenderFrameProxyHost(site_instance, frame_tree_node_); |
| 1509 proxy_hosts_[site_instance->GetId()] = proxy; | 1438 proxy_hosts_[site_instance->GetId()] = proxy; |
| 1510 pending_render_frame_host->SwapOut(proxy); | 1439 pending_render_frame_host->SwapOut(proxy); |
| 1511 if (frame_tree_node_->IsMainFrame()) | 1440 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); |
| 1512 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); | |
| 1513 } else { | 1441 } else { |
| 1514 // We won't be coming back, so delete this one. | 1442 // We won't be coming back, so delete this one. |
| 1515 pending_render_frame_host.reset(); | 1443 pending_render_frame_host.reset(); |
| 1516 } | 1444 } |
| 1517 | 1445 |
| 1518 pending_web_ui_.reset(); | 1446 pending_web_ui_.reset(); |
| 1519 pending_and_current_web_ui_.reset(); | 1447 pending_and_current_web_ui_.reset(); |
| 1520 } | 1448 } |
| 1521 | 1449 |
| 1522 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 1450 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1543 | 1471 |
| 1544 return old_render_frame_host.Pass(); | 1472 return old_render_frame_host.Pass(); |
| 1545 } | 1473 } |
| 1546 | 1474 |
| 1547 bool RenderFrameHostManager::IsRVHOnSwappedOutList( | 1475 bool RenderFrameHostManager::IsRVHOnSwappedOutList( |
| 1548 RenderViewHostImpl* rvh) const { | 1476 RenderViewHostImpl* rvh) const { |
| 1549 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost( | 1477 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost( |
| 1550 rvh->GetSiteInstance()); | 1478 rvh->GetSiteInstance()); |
| 1551 if (!proxy) | 1479 if (!proxy) |
| 1552 return false; | 1480 return false; |
| 1553 // If there is a proxy without RFH, it is for a subframe in the SiteInstance | |
| 1554 // of |rvh|. Subframes should be ignored in this case. | |
| 1555 if (!proxy->render_frame_host()) | |
| 1556 return false; | |
| 1557 return IsOnSwappedOutList(proxy->render_frame_host()); | 1481 return IsOnSwappedOutList(proxy->render_frame_host()); |
| 1558 } | 1482 } |
| 1559 | 1483 |
| 1560 bool RenderFrameHostManager::IsOnSwappedOutList( | 1484 bool RenderFrameHostManager::IsOnSwappedOutList( |
| 1561 RenderFrameHostImpl* rfh) const { | 1485 RenderFrameHostImpl* rfh) const { |
| 1562 if (!rfh->GetSiteInstance()) | 1486 if (!rfh->GetSiteInstance()) |
| 1563 return false; | 1487 return false; |
| 1564 | 1488 |
| 1565 RenderFrameProxyHostMap::const_iterator iter = proxy_hosts_.find( | 1489 RenderFrameProxyHostMap::const_iterator iter = proxy_hosts_.find( |
| 1566 rfh->GetSiteInstance()->GetId()); | 1490 rfh->GetSiteInstance()->GetId()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1582 SiteInstance* instance) const { | 1506 SiteInstance* instance) const { |
| 1583 RenderFrameProxyHostMap::const_iterator iter = | 1507 RenderFrameProxyHostMap::const_iterator iter = |
| 1584 proxy_hosts_.find(instance->GetId()); | 1508 proxy_hosts_.find(instance->GetId()); |
| 1585 if (iter != proxy_hosts_.end()) | 1509 if (iter != proxy_hosts_.end()) |
| 1586 return iter->second; | 1510 return iter->second; |
| 1587 | 1511 |
| 1588 return NULL; | 1512 return NULL; |
| 1589 } | 1513 } |
| 1590 | 1514 |
| 1591 } // namespace content | 1515 } // namespace content |
| OLD | NEW |