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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 RenderFrameHostManager::~RenderFrameHostManager() { | 86 RenderFrameHostManager::~RenderFrameHostManager() { |
87 if (pending_render_frame_host_) | 87 if (pending_render_frame_host_) |
88 CancelPending(); | 88 CancelPending(); |
89 | 89 |
90 if (cross_process_frame_connector_) | 90 if (cross_process_frame_connector_) |
91 delete cross_process_frame_connector_; | 91 delete cross_process_frame_connector_; |
92 | 92 |
93 // We should always have a current RenderFrameHost except in some tests. | 93 // We should always have a current RenderFrameHost except in some tests. |
94 render_frame_host_.reset(); | 94 render_frame_host_.reset(); |
95 | 95 |
96 // Delete any swapped out RenderFrameHosts. | 96 // Delete any swapped out RenderFrameHosts after sending a message to delete |
97 // their counterparts in the renderer process. | |
98 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); | |
99 iter != proxy_hosts_.end(); | |
100 ++iter) { | |
101 iter->second->DeleteRendererProxy(); | |
102 } | |
97 STLDeleteValues(&proxy_hosts_); | 103 STLDeleteValues(&proxy_hosts_); |
98 } | 104 } |
99 | 105 |
100 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 106 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
101 SiteInstance* site_instance, | 107 SiteInstance* site_instance, |
102 int view_routing_id, | 108 int view_routing_id, |
103 int frame_routing_id) { | 109 int frame_routing_id) { |
104 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It | 110 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It |
105 // is important to immediately give this SiteInstance to a RenderViewHost so | 111 // is important to immediately give this SiteInstance to a RenderViewHost so |
106 // that the SiteInstance is ref counted. | 112 // that the SiteInstance is ref counted. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 return NULL; // We weren't able to create a pending render frame host. | 174 return NULL; // We weren't able to create a pending render frame host. |
169 | 175 |
170 // If the current render_frame_host_ isn't live, we should create it so | 176 // If the current render_frame_host_ isn't live, we should create it so |
171 // that we don't show a sad tab while the dest_render_frame_host fetches | 177 // that we don't show a sad tab while the dest_render_frame_host fetches |
172 // its first page. (Bug 1145340) | 178 // its first page. (Bug 1145340) |
173 if (dest_render_frame_host != render_frame_host_ && | 179 if (dest_render_frame_host != render_frame_host_ && |
174 !render_frame_host_->render_view_host()->IsRenderViewLive()) { | 180 !render_frame_host_->render_view_host()->IsRenderViewLive()) { |
175 // Note: we don't call InitRenderView here because we are navigating away | 181 // Note: we don't call InitRenderView here because we are navigating away |
176 // soon anyway, and we don't have the NavigationEntry for this host. | 182 // soon anyway, and we don't have the NavigationEntry for this host. |
177 delegate_->CreateRenderViewForRenderManager( | 183 delegate_->CreateRenderViewForRenderManager( |
178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, NULL); | 184 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, |
185 MSG_ROUTING_NONE, NULL); | |
179 } | 186 } |
180 | 187 |
181 // If the renderer crashed, then try to create a new one to satisfy this | 188 // If the renderer crashed, then try to create a new one to satisfy this |
182 // navigation request. | 189 // navigation request. |
183 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { | 190 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { |
184 // Recreate the opener chain. | 191 // Recreate the opener chain. |
185 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | 192 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( |
186 dest_render_frame_host->GetSiteInstance()); | 193 dest_render_frame_host->GetSiteInstance()); |
187 if (!InitRenderView(dest_render_frame_host->render_view_host(), | 194 if (!InitRenderView(dest_render_frame_host->render_view_host(), |
188 opener_route_id)) | 195 opener_route_id, MSG_ROUTING_NONE)) |
189 return NULL; | 196 return NULL; |
190 | 197 |
191 // Now that we've created a new renderer, be sure to hide it if it isn't | 198 // Now that we've created a new renderer, be sure to hide it if it isn't |
192 // our primary one. Otherwise, we might crash if we try to call Show() | 199 // our primary one. Otherwise, we might crash if we try to call Show() |
193 // on it later. | 200 // on it later. |
194 if (dest_render_frame_host != render_frame_host_ && | 201 if (dest_render_frame_host != render_frame_host_ && |
195 dest_render_frame_host->render_view_host()->GetView()) { | 202 dest_render_frame_host->render_view_host()->GetView()) { |
196 dest_render_frame_host->render_view_host()->GetView()->Hide(); | 203 dest_render_frame_host->render_view_host()->GetView()->Hide(); |
197 } else if (frame_tree_node_->IsMainFrame()) { | 204 } else if (frame_tree_node_->IsMainFrame()) { |
198 // This is our primary renderer, notify here as we won't be calling | 205 // This is our primary renderer, notify here as we won't be calling |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 // The same CrossProcessFrameConnector is used for subsequent cross- | 506 // The same CrossProcessFrameConnector is used for subsequent cross- |
500 // process navigations, but it will be destroyed if the Frame is | 507 // process navigations, but it will be destroyed if the Frame is |
501 // navigated back to the same site instance as its parent. | 508 // navigated back to the same site instance as its parent. |
502 // TODO(kenrb): This will change when RenderFrameProxyHost is created. | 509 // TODO(kenrb): This will change when RenderFrameProxyHost is created. |
503 if (!cross_process_frame_connector_) { | 510 if (!cross_process_frame_connector_) { |
504 cross_process_frame_connector_ = | 511 cross_process_frame_connector_ = |
505 new CrossProcessFrameConnector(render_frame_host_.get()); | 512 new CrossProcessFrameConnector(render_frame_host_.get()); |
506 } | 513 } |
507 } | 514 } |
508 | 515 |
516 // Create the RenderFrameProxyHost that will replace the RenderFrameHost | |
517 // which is swapping out. | |
518 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | |
519 render_frame_host_->GetSiteInstance(), frame_tree_node_); | |
520 proxy_hosts_[render_frame_host_->GetSiteInstance()->GetId()] = proxy; | |
Charlie Reis
2014/05/15 00:32:50
To be clear, render_frame_host_ (and its SiteInsta
ncarter (slow)
2014/05/15 00:42:23
What guarantees that there's not already something
nasko
2014/05/15 18:47:13
It actually won't exist in two places. Here only a
nasko
2014/05/15 18:47:13
I don't think there is a guarantee and I found one
Charlie Reis
2014/05/15 22:55:00
In that case, should IsOnSwappedOutList(RFH) will
nasko
2014/05/15 23:36:49
The only way for IsOnSwappedOutList(RFH) to return
Charlie Reis
2014/05/16 18:54:07
I think I confused myself-- I must have been looki
| |
521 | |
509 // Tell the old frame it is being swapped out. This will fire the unload | 522 // Tell the old frame it is being swapped out. This will fire the unload |
510 // handler in the background (without firing the beforeunload handler a second | 523 // handler in the background (without firing the beforeunload handler a second |
511 // time). When the navigation completes, we will send a message to the | 524 // time). When the navigation completes, we will send a message to the |
512 // ResourceDispatcherHost, allowing the pending RVH's response to resume. | 525 // ResourceDispatcherHost, allowing the pending RVH's response to resume. |
513 render_frame_host_->SwapOut(); | 526 render_frame_host_->SwapOut(proxy); |
514 | 527 |
515 // ResourceDispatcherHost has told us to run the onunload handler, which | 528 // ResourceDispatcherHost has told us to run the onunload handler, which |
516 // means it is not a download or unsafe page, and we are going to perform the | 529 // means it is not a download or unsafe page, and we are going to perform the |
517 // navigation. Thus, we no longer need to remember that the RenderFrameHost | 530 // navigation. Thus, we no longer need to remember that the RenderFrameHost |
518 // is part of a pending cross-site request. | 531 // is part of a pending cross-site request. |
519 if (pending_render_frame_host_) { | 532 if (pending_render_frame_host_) { |
520 pending_render_frame_host_->render_view_host()-> | 533 pending_render_frame_host_->render_view_host()-> |
521 SetHasPendingCrossSiteRequest(false); | 534 SetHasPendingCrossSiteRequest(false); |
522 } | 535 } |
523 } | 536 } |
(...skipping 27 matching lines...) Expand all Loading... | |
551 int32 site_instance_id, | 564 int32 site_instance_id, |
552 FrameTreeNode* node) { | 565 FrameTreeNode* node) { |
553 RenderFrameProxyHostMap::iterator iter = | 566 RenderFrameProxyHostMap::iterator iter = |
554 node->render_manager()->proxy_hosts_.find(site_instance_id); | 567 node->render_manager()->proxy_hosts_.find(site_instance_id); |
555 if (iter != node->render_manager()->proxy_hosts_.end()) { | 568 if (iter != node->render_manager()->proxy_hosts_.end()) { |
556 RenderFrameProxyHost* proxy = iter->second; | 569 RenderFrameProxyHost* proxy = iter->second; |
557 // If the RVH is pending swap out, it needs to switch state to | 570 // If the RVH is pending swap out, it needs to switch state to |
558 // pending shutdown. Otherwise it is deleted. | 571 // pending shutdown. Otherwise it is deleted. |
559 if (proxy->render_view_host()->rvh_state() == | 572 if (proxy->render_view_host()->rvh_state() == |
560 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { | 573 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { |
561 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = proxy->PassFrameHost(); | 574 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = |
575 proxy->PassFrameHostOwnership(); | |
562 | 576 |
563 swapped_out_rfh->SetPendingShutdown(base::Bind( | 577 swapped_out_rfh->SetPendingShutdown(base::Bind( |
564 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | 578 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, |
565 node->render_manager()->weak_factory_.GetWeakPtr(), | 579 node->render_manager()->weak_factory_.GetWeakPtr(), |
566 site_instance_id, | 580 site_instance_id, |
567 swapped_out_rfh.get())); | 581 swapped_out_rfh.get())); |
568 RFHPendingDeleteMap::iterator pending_delete_iter = | 582 RFHPendingDeleteMap::iterator pending_delete_iter = |
569 node->render_manager()->pending_delete_hosts_.find(site_instance_id); | 583 node->render_manager()->pending_delete_hosts_.find(site_instance_id); |
570 if (pending_delete_iter == | 584 if (pending_delete_iter == |
571 node->render_manager()->pending_delete_hosts_.end() || | 585 node->render_manager()->pending_delete_hosts_.end() || |
572 pending_delete_iter->second.get() != swapped_out_rfh) { | 586 pending_delete_iter->second.get() != swapped_out_rfh) { |
573 node->render_manager()->pending_delete_hosts_[site_instance_id] = | 587 node->render_manager()->pending_delete_hosts_[site_instance_id] = |
574 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); | 588 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); |
575 } | 589 } |
576 } else { | 590 } else { |
591 proxy->DeleteRendererProxy(); | |
577 delete proxy; | 592 delete proxy; |
578 } | 593 } |
579 node->render_manager()->proxy_hosts_.erase(site_instance_id); | 594 node->render_manager()->proxy_hosts_.erase(site_instance_id); |
580 } | 595 } |
581 | 596 |
582 return true; | 597 return true; |
583 } | 598 } |
584 | 599 |
585 bool RenderFrameHostManager::ShouldTransitionCrossSite() { | 600 bool RenderFrameHostManager::ShouldTransitionCrossSite() { |
586 // False in the single-process mode, as it makes RVHs to accumulate | 601 // False in the single-process mode, as it makes RVHs to accumulate |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
891 | 906 |
892 // Check if we've already created an RFH for this SiteInstance. If so, try | 907 // Check if we've already created an RFH for this SiteInstance. If so, try |
893 // to re-use the existing one, which has already been initialized. We'll | 908 // to re-use the existing one, which has already been initialized. We'll |
894 // remove it from the list of swapped out hosts if it commits. | 909 // remove it from the list of swapped out hosts if it commits. |
895 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 910 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
896 | 911 |
897 FrameTreeNode* parent_node = frame_tree_node_->parent(); | 912 FrameTreeNode* parent_node = frame_tree_node_->parent(); |
898 | 913 |
899 if (proxy) { | 914 if (proxy) { |
900 routing_id = proxy->render_view_host()->GetRoutingID(); | 915 routing_id = proxy->render_view_host()->GetRoutingID(); |
916 | |
901 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 917 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
902 // 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. |
903 if (!swapped_out) { | 919 if (!swapped_out) { |
904 new_render_frame_host = proxy->PassFrameHost(); | 920 new_render_frame_host = proxy->PassFrameHostOwnership(); |
921 new_render_frame_host->set_render_frame_proxy(NULL); | |
Charlie Reis
2014/05/15 00:32:50
Would it make sense to do this step inside PassFra
nasko
2014/05/15 18:47:13
Done.
| |
905 new_render_frame_host->GetProcess()->AddPendingView(); | 922 new_render_frame_host->GetProcess()->AddPendingView(); |
906 | 923 |
907 proxy_hosts_.erase(instance->GetId()); | 924 proxy_hosts_.erase(instance->GetId()); |
908 delete proxy; | 925 delete proxy; |
909 } else { | 926 } else { |
910 // Detect if this is a cross-process child frame that is navigating | 927 // Detect if this is a cross-process child frame that is navigating |
911 // back to the same SiteInstance as its parent. | 928 // back to the same SiteInstance as its parent. |
912 if (parent_node && cross_process_frame_connector_ && | 929 if (parent_node && cross_process_frame_connector_ && |
913 render_frame_host_->GetSiteInstance() == parent_node-> | 930 render_frame_host_->GetSiteInstance() == parent_node-> |
914 render_manager()->current_frame_host()->GetSiteInstance()) { | 931 render_manager()->current_frame_host()->GetSiteInstance()) { |
915 delete cross_process_frame_connector_; | 932 delete cross_process_frame_connector_; |
916 cross_process_frame_connector_ = NULL; | 933 cross_process_frame_connector_ = NULL; |
917 } | 934 } |
918 } | 935 } |
919 } else { | 936 } else { |
920 // Create a new RenderFrameHost if we don't find an existing one. | 937 // Create a new RenderFrameHost if we don't find an existing one. |
921 new_render_frame_host = CreateRenderFrameHost( | 938 new_render_frame_host = CreateRenderFrameHost( |
922 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); | 939 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); |
923 RenderViewHostImpl* render_view_host = | 940 RenderViewHostImpl* render_view_host = |
924 new_render_frame_host->render_view_host(); | 941 new_render_frame_host->render_view_host(); |
942 int proxy_routing_id = MSG_ROUTING_NONE; | |
925 | 943 |
926 // Prevent the process from exiting while we're trying to navigate in it. | 944 // Prevent the process from exiting while we're trying to navigate in it. |
927 // Otherwise, if the new RFH is swapped out already, store it. | 945 // Otherwise, if the new RFH is swapped out already, store it. |
928 if (!swapped_out) { | 946 if (!swapped_out) { |
929 new_render_frame_host->GetProcess()->AddPendingView(); | 947 new_render_frame_host->GetProcess()->AddPendingView(); |
930 } else { | 948 } else { |
931 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost( | 949 if (!proxy) { |
Charlie Reis
2014/05/15 00:32:50
We already know there's no proxy, since we're in t
nasko
2014/05/15 18:47:13
Done.
| |
932 new_render_frame_host.Pass()); | 950 proxy = new RenderFrameProxyHost( |
951 new_render_frame_host->GetSiteInstance(), frame_tree_node_); | |
952 } | |
953 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); | |
954 proxy_routing_id = proxy->GetRoutingID(); | |
955 proxy_hosts_[instance->GetId()] = proxy; | |
933 } | 956 } |
934 | 957 |
935 bool success = InitRenderView(render_view_host, opener_route_id); | 958 bool success = InitRenderView( |
959 render_view_host, opener_route_id, proxy_routing_id); | |
936 if (success && frame_tree_node_->IsMainFrame()) { | 960 if (success && frame_tree_node_->IsMainFrame()) { |
937 // Don't show the main frame's view until we get a DidNavigate from it. | 961 // Don't show the main frame's view until we get a DidNavigate from it. |
938 render_view_host->GetView()->Hide(); | 962 render_view_host->GetView()->Hide(); |
939 } else if (!swapped_out && pending_render_frame_host_) { | 963 } else if (!swapped_out && pending_render_frame_host_) { |
940 CancelPending(); | 964 CancelPending(); |
941 } | 965 } |
942 routing_id = render_view_host->GetRoutingID(); | 966 routing_id = render_view_host->GetRoutingID(); |
943 } | 967 } |
944 | 968 |
945 // Use this as our new pending RFH if it isn't swapped out. | 969 // Use this as our new pending RFH if it isn't swapped out. |
946 if (!swapped_out) | 970 if (!swapped_out) |
947 pending_render_frame_host_ = new_render_frame_host.Pass(); | 971 pending_render_frame_host_ = new_render_frame_host.Pass(); |
948 | 972 |
949 return routing_id; | 973 return routing_id; |
950 } | 974 } |
951 | 975 |
952 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, | 976 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, |
953 int opener_route_id) { | 977 int opener_route_id, |
978 int proxy_routing_id) { | |
954 // We may have initialized this RenderViewHost for another RenderFrameHost. | 979 // We may have initialized this RenderViewHost for another RenderFrameHost. |
955 if (render_view_host->IsRenderViewLive()) | 980 if (render_view_host->IsRenderViewLive()) |
956 return true; | 981 return true; |
957 | 982 |
958 // If the pending navigation is to a WebUI and the RenderView is not in a | 983 // If the pending navigation is to a WebUI and the RenderView is not in a |
959 // guest process, tell the RenderViewHost about any bindings it will need | 984 // guest process, tell the RenderViewHost about any bindings it will need |
960 // enabled. | 985 // enabled. |
961 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { | 986 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { |
962 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 987 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
963 } else { | 988 } else { |
964 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 989 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
965 // process unless it's swapped out. | 990 // process unless it's swapped out. |
966 RenderViewHostImpl* rvh_impl = | 991 RenderViewHostImpl* rvh_impl = |
967 static_cast<RenderViewHostImpl*>(render_view_host); | 992 static_cast<RenderViewHostImpl*>(render_view_host); |
968 if (!rvh_impl->IsSwappedOut()) { | 993 if (!rvh_impl->IsSwappedOut()) { |
969 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 994 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
970 render_view_host->GetProcess()->GetID())); | 995 render_view_host->GetProcess()->GetID())); |
971 } | 996 } |
972 } | 997 } |
973 | 998 |
974 return delegate_->CreateRenderViewForRenderManager( | 999 return delegate_->CreateRenderViewForRenderManager( |
975 render_view_host, opener_route_id, cross_process_frame_connector_); | 1000 render_view_host, opener_route_id, proxy_routing_id, |
1001 cross_process_frame_connector_); | |
976 } | 1002 } |
977 | 1003 |
978 void RenderFrameHostManager::CommitPending() { | 1004 void RenderFrameHostManager::CommitPending() { |
979 // First check whether we're going to want to focus the location bar after | 1005 // First check whether we're going to want to focus the location bar after |
980 // this commit. We do this now because the navigation hasn't formally | 1006 // this commit. We do this now because the navigation hasn't formally |
981 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1007 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
982 // this triggers won't be able to figure out what's going on. | 1008 // this triggers won't be able to figure out what's going on. |
983 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1009 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
984 | 1010 |
985 // We expect SwapOutOldPage to have canceled any modal dialogs and told the | 1011 // We expect SwapOutOldPage to have canceled any modal dialogs and told the |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1086 } | 1112 } |
1087 | 1113 |
1088 // If the old RFH is live, we are swapping it out and should keep track of | 1114 // If the old RFH is live, we are swapping it out and should keep track of |
1089 // it in case we navigate back to it, or it is waiting for the unload event | 1115 // it in case we navigate back to it, or it is waiting for the unload event |
1090 // to execute in the background. | 1116 // to execute in the background. |
1091 // TODO(creis): Swap out the subframe in --site-per-process. | 1117 // TODO(creis): Swap out the subframe in --site-per-process. |
1092 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 1118 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) |
1093 DCHECK(old_render_frame_host->is_swapped_out() || | 1119 DCHECK(old_render_frame_host->is_swapped_out() || |
1094 !RenderViewHostImpl::IsRVHStateActive( | 1120 !RenderViewHostImpl::IsRVHStateActive( |
1095 old_render_frame_host->render_view_host()->rvh_state())); | 1121 old_render_frame_host->render_view_host()->rvh_state())); |
1096 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make | |
1097 // sure we don't get different rvh instances for the same site instance | |
1098 // in the same rvhmgr. | |
1099 // TODO(creis): Clean this up. | |
1100 RenderFrameProxyHostMap::iterator iter = | |
1101 proxy_hosts_.find(old_site_instance_id); | |
1102 if (iter != proxy_hosts_.end() && | |
1103 iter->second->render_frame_host() != old_render_frame_host) { | |
1104 // Delete the proxy that will be replaced in the map to avoid a leak. | |
1105 delete iter->second; | |
1106 } | |
1107 | 1122 |
1108 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, | 1123 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, |
1109 // the RenderFrameHost should be put in the map of RenderFrameHosts pending | 1124 // the RenderFrameHost should be put in the map of RenderFrameHosts pending |
1110 // shutdown. Otherwise, it is stored in the map of proxy hosts. | 1125 // shutdown. Otherwise, it is stored in the map of proxy hosts. |
1111 if (old_render_frame_host->render_view_host()->rvh_state() == | 1126 if (old_render_frame_host->render_view_host()->rvh_state() == |
1112 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { | 1127 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { |
1113 proxy_hosts_.erase(old_site_instance_id); | 1128 // The proxy for this RenderFrameHost is created when sending the |
1129 // SwapOut message, so check if it already exists and delete it. | |
1130 RenderFrameProxyHostMap::iterator iter = | |
1131 proxy_hosts_.find(old_site_instance_id); | |
Charlie Reis
2014/05/15 00:32:50
nit: Wrong indent.
nasko
2014/05/15 18:47:13
Done.
| |
1132 if (iter != proxy_hosts_.end()) { | |
1133 iter->second->DeleteRendererProxy(); | |
1134 delete iter->second; | |
1135 proxy_hosts_.erase(iter); | |
1136 } | |
1114 RFHPendingDeleteMap::iterator pending_delete_iter = | 1137 RFHPendingDeleteMap::iterator pending_delete_iter = |
1115 pending_delete_hosts_.find(old_site_instance_id); | 1138 pending_delete_hosts_.find(old_site_instance_id); |
1116 if (pending_delete_iter == pending_delete_hosts_.end() || | 1139 if (pending_delete_iter == pending_delete_hosts_.end() || |
1117 pending_delete_iter->second.get() != old_render_frame_host) { | 1140 pending_delete_iter->second.get() != old_render_frame_host) { |
1118 pending_delete_hosts_[old_site_instance_id] = | 1141 pending_delete_hosts_[old_site_instance_id] = |
1119 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); | 1142 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); |
1120 } | 1143 } |
1121 } else { | 1144 } else { |
1145 // Capture the active view count on the old RFH SiteInstance, since the | |
1146 // ownership will be passed into the proxy and the pointer will be invalid. | |
1147 int active_view_count = static_cast<SiteInstanceImpl*>( | |
1148 old_render_frame_host->GetSiteInstance())->active_view_count(); | |
Charlie Reis
2014/05/15 00:32:50
nit: Wrong indent.
nasko
2014/05/15 18:47:13
Done.
| |
1149 | |
1150 RenderFrameProxyHostMap::iterator iter = | |
1151 proxy_hosts_.find(old_site_instance_id); | |
1152 CHECK(iter != proxy_hosts_.end()); | |
1153 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); | |
1154 | |
1122 // If there are no active views in this SiteInstance, it means that | 1155 // If there are no active views in this SiteInstance, it means that |
1123 // this RFH was the last active one in the SiteInstance. Now that we | 1156 // this RFH was the last active one in the SiteInstance. Now that we |
1124 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs | 1157 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
1125 // in this SiteInstance. We do this after ensuring the RFH is on the | 1158 // in this SiteInstance. |
1126 // swapped out list to simplify the deletion. | 1159 if (!active_view_count) { |
Charlie Reis
2014/05/15 00:32:50
nit: No braces needed.
nasko
2014/05/15 18:47:13
Done.
| |
1127 if (!static_cast<SiteInstanceImpl*>( | |
1128 old_render_frame_host->GetSiteInstance())->active_view_count()) { | |
1129 old_render_frame_host.reset(); | |
1130 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1160 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
1131 } else { | |
1132 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost( | |
1133 old_render_frame_host.Pass()); | |
1134 } | 1161 } |
1135 } | 1162 } |
1136 } | 1163 } |
1137 | 1164 |
1138 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1165 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
1139 int32 site_instance_id) { | 1166 int32 site_instance_id) { |
1140 // First remove any swapped out RFH for this SiteInstance from our own list. | 1167 // First remove any swapped out RFH for this SiteInstance from our own list. |
1141 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1168 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
1142 | 1169 |
1143 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1170 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1336 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1363 pending_render_frame_host->GetProcess()->RemovePendingView(); |
1337 | 1364 |
1338 // If the SiteInstance for the pending RFH is being used by others, don't | 1365 // If the SiteInstance for the pending RFH is being used by others, don't |
1339 // delete the RFH, just swap it out and it can be reused at a later point. | 1366 // delete the RFH, just swap it out and it can be reused at a later point. |
1340 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( | 1367 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( |
1341 pending_render_frame_host->GetSiteInstance()); | 1368 pending_render_frame_host->GetSiteInstance()); |
1342 if (site_instance->active_view_count() > 1) { | 1369 if (site_instance->active_view_count() > 1) { |
1343 // Any currently suspended navigations are no longer needed. | 1370 // Any currently suspended navigations are no longer needed. |
1344 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1371 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
1345 | 1372 |
1346 pending_render_frame_host->SwapOut(); | 1373 RenderFrameProxyHost* proxy = |
1347 | 1374 new RenderFrameProxyHost(site_instance, frame_tree_node_); |
1348 proxy_hosts_[site_instance->GetId()] = new RenderFrameProxyHost( | 1375 pending_render_frame_host->SwapOut(proxy); |
1349 pending_render_frame_host.Pass()); | 1376 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); |
1377 proxy_hosts_[site_instance->GetId()] = proxy; | |
Charlie Reis
2014/05/15 00:32:50
I'm a little uncomfortable that we put the proxy i
nasko
2014/05/15 18:47:13
This was just a honest omission, not intentional.
| |
1350 } else { | 1378 } else { |
1351 // We won't be coming back, so delete this one. | 1379 // We won't be coming back, so delete this one. |
1352 pending_render_frame_host.reset(); | 1380 pending_render_frame_host.reset(); |
1353 } | 1381 } |
1354 | 1382 |
1355 pending_web_ui_.reset(); | 1383 pending_web_ui_.reset(); |
1356 pending_and_current_web_ui_.reset(); | 1384 pending_and_current_web_ui_.reset(); |
1357 } | 1385 } |
1358 | 1386 |
1359 bool RenderFrameHostManager::IsRVHOnSwappedOutList( | 1387 bool RenderFrameHostManager::IsRVHOnSwappedOutList( |
(...skipping 30 matching lines...) Expand all Loading... | |
1390 SiteInstance* instance) const { | 1418 SiteInstance* instance) const { |
1391 RenderFrameProxyHostMap::const_iterator iter = | 1419 RenderFrameProxyHostMap::const_iterator iter = |
1392 proxy_hosts_.find(instance->GetId()); | 1420 proxy_hosts_.find(instance->GetId()); |
1393 if (iter != proxy_hosts_.end()) | 1421 if (iter != proxy_hosts_.end()) |
1394 return iter->second; | 1422 return iter->second; |
1395 | 1423 |
1396 return NULL; | 1424 return NULL; |
1397 } | 1425 } |
1398 | 1426 |
1399 } // namespace content | 1427 } // namespace content |
OLD | NEW |