| 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 157 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. | 168 return NULL; // We weren't able to create a pending render frame host. |
| 169 | 169 |
| 170 // If the current render_frame_host_ isn't live, we should create it so | 170 // 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 | 171 // that we don't show a sad tab while the dest_render_frame_host fetches |
| 172 // its first page. (Bug 1145340) | 172 // its first page. (Bug 1145340) |
| 173 if (dest_render_frame_host != render_frame_host_ && | 173 if (dest_render_frame_host != render_frame_host_ && |
| 174 !render_frame_host_->render_view_host()->IsRenderViewLive()) { | 174 !render_frame_host_->render_view_host()->IsRenderViewLive()) { |
| 175 // Note: we don't call InitRenderView here because we are navigating away | 175 // 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. | 176 // soon anyway, and we don't have the NavigationEntry for this host. |
| 177 delegate_->CreateRenderViewForRenderManager( | 177 delegate_->CreateRenderViewForRenderManager( |
| 178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, NULL); | 178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, |
| 179 MSG_ROUTING_NONE, NULL); |
| 179 } | 180 } |
| 180 | 181 |
| 181 // If the renderer crashed, then try to create a new one to satisfy this | 182 // If the renderer crashed, then try to create a new one to satisfy this |
| 182 // navigation request. | 183 // navigation request. |
| 183 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { | 184 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { |
| 184 // Recreate the opener chain. | 185 // Recreate the opener chain. |
| 185 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | 186 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( |
| 186 dest_render_frame_host->GetSiteInstance()); | 187 dest_render_frame_host->GetSiteInstance()); |
| 187 if (!InitRenderView(dest_render_frame_host->render_view_host(), | 188 if (!InitRenderView(dest_render_frame_host->render_view_host(), |
| 188 opener_route_id)) | 189 opener_route_id, MSG_ROUTING_NONE)) |
| 189 return NULL; | 190 return NULL; |
| 190 | 191 |
| 191 // Now that we've created a new renderer, be sure to hide it if it isn't | 192 // 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() | 193 // our primary one. Otherwise, we might crash if we try to call Show() |
| 193 // on it later. | 194 // on it later. |
| 194 if (dest_render_frame_host != render_frame_host_ && | 195 if (dest_render_frame_host != render_frame_host_ && |
| 195 dest_render_frame_host->render_view_host()->GetView()) { | 196 dest_render_frame_host->render_view_host()->GetView()) { |
| 196 dest_render_frame_host->render_view_host()->GetView()->Hide(); | 197 dest_render_frame_host->render_view_host()->GetView()->Hide(); |
| 197 } else if (frame_tree_node_->IsMainFrame()) { | 198 } else if (frame_tree_node_->IsMainFrame()) { |
| 198 // This is our primary renderer, notify here as we won't be calling | 199 // This is our primary renderer, notify here as we won't be calling |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 } | 445 } |
| 445 | 446 |
| 446 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers. | 447 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers. |
| 447 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) { | 448 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) { |
| 448 // Notify all swapped out hosts, including the pending RVH. | 449 // Notify all swapped out hosts, including the pending RVH. |
| 449 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); | 450 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); |
| 450 iter != proxy_hosts_.end(); | 451 iter != proxy_hosts_.end(); |
| 451 ++iter) { | 452 ++iter) { |
| 452 DCHECK_NE(iter->second->GetSiteInstance(), | 453 DCHECK_NE(iter->second->GetSiteInstance(), |
| 453 current_frame_host()->GetSiteInstance()); | 454 current_frame_host()->GetSiteInstance()); |
| 454 iter->second->render_view_host()->DisownOpener(); | 455 iter->second->GetRenderViewHost()->DisownOpener(); |
| 455 } | 456 } |
| 456 } | 457 } |
| 457 | 458 |
| 458 void RenderFrameHostManager::RendererProcessClosing( | 459 void RenderFrameHostManager::RendererProcessClosing( |
| 459 RenderProcessHost* render_process_host) { | 460 RenderProcessHost* render_process_host) { |
| 460 // Remove any swapped out RVHs from this process, so that we don't try to | 461 // Remove any swapped out RVHs from this process, so that we don't try to |
| 461 // swap them back in while the process is exiting. Start by finding them, | 462 // swap them back in while the process is exiting. Start by finding them, |
| 462 // since there could be more than one. | 463 // since there could be more than one. |
| 463 std::list<int> ids_to_remove; | 464 std::list<int> ids_to_remove; |
| 464 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); | 465 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 // The same CrossProcessFrameConnector is used for subsequent cross- | 500 // The same CrossProcessFrameConnector is used for subsequent cross- |
| 500 // process navigations, but it will be destroyed if the Frame is | 501 // process navigations, but it will be destroyed if the Frame is |
| 501 // navigated back to the same site instance as its parent. | 502 // navigated back to the same site instance as its parent. |
| 502 // TODO(kenrb): This will change when RenderFrameProxyHost is created. | 503 // TODO(kenrb): This will change when RenderFrameProxyHost is created. |
| 503 if (!cross_process_frame_connector_) { | 504 if (!cross_process_frame_connector_) { |
| 504 cross_process_frame_connector_ = | 505 cross_process_frame_connector_ = |
| 505 new CrossProcessFrameConnector(render_frame_host_.get()); | 506 new CrossProcessFrameConnector(render_frame_host_.get()); |
| 506 } | 507 } |
| 507 } | 508 } |
| 508 | 509 |
| 510 // Create the RenderFrameProxyHost that will replace the |
| 511 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted |
| 512 // from the map and not leaked. |
| 513 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find( |
| 514 render_frame_host_->GetSiteInstance()->GetId()); |
| 515 if (iter != proxy_hosts_.end()) { |
| 516 delete iter->second; |
| 517 proxy_hosts_.erase(iter); |
| 518 } |
| 519 |
| 520 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
| 521 render_frame_host_->GetSiteInstance(), frame_tree_node_); |
| 522 proxy_hosts_[render_frame_host_->GetSiteInstance()->GetId()] = proxy; |
| 523 |
| 509 // Tell the old frame it is being swapped out. This will fire the unload | 524 // 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 | 525 // handler in the background (without firing the beforeunload handler a second |
| 511 // time). When the navigation completes, we will send a message to the | 526 // time). When the navigation completes, we will send a message to the |
| 512 // ResourceDispatcherHost, allowing the pending RVH's response to resume. | 527 // ResourceDispatcherHost, allowing the pending RVH's response to resume. |
| 513 render_frame_host_->SwapOut(); | 528 render_frame_host_->SwapOut(proxy); |
| 514 | 529 |
| 515 // ResourceDispatcherHost has told us to run the onunload handler, which | 530 // 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 | 531 // 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 | 532 // navigation. Thus, we no longer need to remember that the RenderFrameHost |
| 518 // is part of a pending cross-site request. | 533 // is part of a pending cross-site request. |
| 519 if (pending_render_frame_host_) { | 534 if (pending_render_frame_host_) { |
| 520 pending_render_frame_host_->render_view_host()-> | 535 pending_render_frame_host_->render_view_host()-> |
| 521 SetHasPendingCrossSiteRequest(false); | 536 SetHasPendingCrossSiteRequest(false); |
| 522 } | 537 } |
| 523 } | 538 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 549 | 564 |
| 550 bool RenderFrameHostManager::ClearProxiesInSiteInstance( | 565 bool RenderFrameHostManager::ClearProxiesInSiteInstance( |
| 551 int32 site_instance_id, | 566 int32 site_instance_id, |
| 552 FrameTreeNode* node) { | 567 FrameTreeNode* node) { |
| 553 RenderFrameProxyHostMap::iterator iter = | 568 RenderFrameProxyHostMap::iterator iter = |
| 554 node->render_manager()->proxy_hosts_.find(site_instance_id); | 569 node->render_manager()->proxy_hosts_.find(site_instance_id); |
| 555 if (iter != node->render_manager()->proxy_hosts_.end()) { | 570 if (iter != node->render_manager()->proxy_hosts_.end()) { |
| 556 RenderFrameProxyHost* proxy = iter->second; | 571 RenderFrameProxyHost* proxy = iter->second; |
| 557 // If the RVH is pending swap out, it needs to switch state to | 572 // If the RVH is pending swap out, it needs to switch state to |
| 558 // pending shutdown. Otherwise it is deleted. | 573 // pending shutdown. Otherwise it is deleted. |
| 559 if (proxy->render_view_host()->rvh_state() == | 574 if (proxy->GetRenderViewHost()->rvh_state() == |
| 560 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { | 575 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { |
| 561 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = proxy->PassFrameHost(); | 576 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = |
| 577 proxy->PassFrameHostOwnership(); |
| 562 | 578 |
| 563 swapped_out_rfh->SetPendingShutdown(base::Bind( | 579 swapped_out_rfh->SetPendingShutdown(base::Bind( |
| 564 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | 580 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, |
| 565 node->render_manager()->weak_factory_.GetWeakPtr(), | 581 node->render_manager()->weak_factory_.GetWeakPtr(), |
| 566 site_instance_id, | 582 site_instance_id, |
| 567 swapped_out_rfh.get())); | 583 swapped_out_rfh.get())); |
| 568 RFHPendingDeleteMap::iterator pending_delete_iter = | 584 RFHPendingDeleteMap::iterator pending_delete_iter = |
| 569 node->render_manager()->pending_delete_hosts_.find(site_instance_id); | 585 node->render_manager()->pending_delete_hosts_.find(site_instance_id); |
| 570 if (pending_delete_iter == | 586 if (pending_delete_iter == |
| 571 node->render_manager()->pending_delete_hosts_.end() || | 587 node->render_manager()->pending_delete_hosts_.end() || |
| 572 pending_delete_iter->second.get() != swapped_out_rfh) { | 588 pending_delete_iter->second.get() != swapped_out_rfh) { |
| 573 node->render_manager()->pending_delete_hosts_[site_instance_id] = | 589 node->render_manager()->pending_delete_hosts_[site_instance_id] = |
| 574 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); | 590 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); |
| 575 } | 591 } |
| 576 } else { | |
| 577 delete proxy; | |
| 578 } | 592 } |
| 593 delete proxy; |
| 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 |
| 587 // in swapped_out_hosts_. | 602 // in swapped_out_hosts_. |
| 588 // True if we are using process-per-site-instance (default) or | 603 // True if we are using process-per-site-instance (default) or |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 905 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 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->GetRenderViewHost()->GetRoutingID(); |
| 901 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 916 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
| 902 // Prevent the process from exiting while we're trying to use it. | 917 // Prevent the process from exiting while we're trying to use it. |
| 903 if (!swapped_out) { | 918 if (!swapped_out) { |
| 904 new_render_frame_host = proxy->PassFrameHost(); | 919 new_render_frame_host = proxy->PassFrameHostOwnership(); |
| 905 new_render_frame_host->GetProcess()->AddPendingView(); | 920 new_render_frame_host->GetProcess()->AddPendingView(); |
| 906 | 921 |
| 907 proxy_hosts_.erase(instance->GetId()); | 922 proxy_hosts_.erase(instance->GetId()); |
| 908 delete proxy; | 923 delete proxy; |
| 909 | 924 |
| 910 // When a new render view is created by the renderer, the new WebContents | 925 // When a new render view is created by the renderer, the new WebContents |
| 911 // gets a RenderViewHost in the SiteInstance of its opener WebContents. | 926 // gets a RenderViewHost in the SiteInstance of its opener WebContents. |
| 912 // If not used in the first navigation, this RVH is swapped out and is not | 927 // If not used in the first navigation, this RVH is swapped out and is not |
| 913 // granted bindings, so we may need to grant them when swapping it in. | 928 // granted bindings, so we may need to grant them when swapping it in. |
| 914 if (pending_web_ui() && !new_render_frame_host->GetProcess()->IsGuest()) { | 929 if (pending_web_ui() && !new_render_frame_host->GetProcess()->IsGuest()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 928 delete cross_process_frame_connector_; | 943 delete cross_process_frame_connector_; |
| 929 cross_process_frame_connector_ = NULL; | 944 cross_process_frame_connector_ = NULL; |
| 930 } | 945 } |
| 931 } | 946 } |
| 932 } else { | 947 } else { |
| 933 // Create a new RenderFrameHost if we don't find an existing one. | 948 // Create a new RenderFrameHost if we don't find an existing one. |
| 934 new_render_frame_host = CreateRenderFrameHost( | 949 new_render_frame_host = CreateRenderFrameHost( |
| 935 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); | 950 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); |
| 936 RenderViewHostImpl* render_view_host = | 951 RenderViewHostImpl* render_view_host = |
| 937 new_render_frame_host->render_view_host(); | 952 new_render_frame_host->render_view_host(); |
| 953 int proxy_routing_id = MSG_ROUTING_NONE; |
| 938 | 954 |
| 939 // Prevent the process from exiting while we're trying to navigate in it. | 955 // Prevent the process from exiting while we're trying to navigate in it. |
| 940 // Otherwise, if the new RFH is swapped out already, store it. | 956 // Otherwise, if the new RFH is swapped out already, store it. |
| 941 if (!swapped_out) { | 957 if (!swapped_out) { |
| 942 new_render_frame_host->GetProcess()->AddPendingView(); | 958 new_render_frame_host->GetProcess()->AddPendingView(); |
| 943 } else { | 959 } else { |
| 944 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost( | 960 proxy = new RenderFrameProxyHost( |
| 945 new_render_frame_host.Pass()); | 961 new_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 962 proxy_hosts_[instance->GetId()] = proxy; |
| 963 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); |
| 964 proxy_routing_id = proxy->GetRoutingID(); |
| 946 } | 965 } |
| 947 | 966 |
| 948 bool success = InitRenderView(render_view_host, opener_route_id); | 967 bool success = InitRenderView( |
| 968 render_view_host, opener_route_id, proxy_routing_id); |
| 949 if (success && frame_tree_node_->IsMainFrame()) { | 969 if (success && frame_tree_node_->IsMainFrame()) { |
| 950 // Don't show the main frame's view until we get a DidNavigate from it. | 970 // Don't show the main frame's view until we get a DidNavigate from it. |
| 951 render_view_host->GetView()->Hide(); | 971 render_view_host->GetView()->Hide(); |
| 952 } else if (!swapped_out && pending_render_frame_host_) { | 972 } else if (!swapped_out && pending_render_frame_host_) { |
| 953 CancelPending(); | 973 CancelPending(); |
| 954 } | 974 } |
| 955 routing_id = render_view_host->GetRoutingID(); | 975 routing_id = render_view_host->GetRoutingID(); |
| 956 } | 976 } |
| 957 | 977 |
| 958 // Use this as our new pending RFH if it isn't swapped out. | 978 // Use this as our new pending RFH if it isn't swapped out. |
| 959 if (!swapped_out) | 979 if (!swapped_out) |
| 960 pending_render_frame_host_ = new_render_frame_host.Pass(); | 980 pending_render_frame_host_ = new_render_frame_host.Pass(); |
| 961 | 981 |
| 962 return routing_id; | 982 return routing_id; |
| 963 } | 983 } |
| 964 | 984 |
| 965 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, | 985 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, |
| 966 int opener_route_id) { | 986 int opener_route_id, |
| 987 int proxy_routing_id) { |
| 967 // We may have initialized this RenderViewHost for another RenderFrameHost. | 988 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 968 if (render_view_host->IsRenderViewLive()) | 989 if (render_view_host->IsRenderViewLive()) |
| 969 return true; | 990 return true; |
| 970 | 991 |
| 971 // If the pending navigation is to a WebUI and the RenderView is not in a | 992 // If the pending navigation is to a WebUI and the RenderView is not in a |
| 972 // guest process, tell the RenderViewHost about any bindings it will need | 993 // guest process, tell the RenderViewHost about any bindings it will need |
| 973 // enabled. | 994 // enabled. |
| 974 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { | 995 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { |
| 975 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 996 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
| 976 } else { | 997 } else { |
| 977 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 998 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
| 978 // process unless it's swapped out. | 999 // process unless it's swapped out. |
| 979 RenderViewHostImpl* rvh_impl = | 1000 RenderViewHostImpl* rvh_impl = |
| 980 static_cast<RenderViewHostImpl*>(render_view_host); | 1001 static_cast<RenderViewHostImpl*>(render_view_host); |
| 981 if (!rvh_impl->IsSwappedOut()) { | 1002 if (!rvh_impl->IsSwappedOut()) { |
| 982 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1003 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
| 983 render_view_host->GetProcess()->GetID())); | 1004 render_view_host->GetProcess()->GetID())); |
| 984 } | 1005 } |
| 985 } | 1006 } |
| 986 | 1007 |
| 987 return delegate_->CreateRenderViewForRenderManager( | 1008 return delegate_->CreateRenderViewForRenderManager( |
| 988 render_view_host, opener_route_id, cross_process_frame_connector_); | 1009 render_view_host, opener_route_id, proxy_routing_id, |
| 1010 cross_process_frame_connector_); |
| 989 } | 1011 } |
| 990 | 1012 |
| 991 void RenderFrameHostManager::CommitPending() { | 1013 void RenderFrameHostManager::CommitPending() { |
| 992 // First check whether we're going to want to focus the location bar after | 1014 // First check whether we're going to want to focus the location bar after |
| 993 // this commit. We do this now because the navigation hasn't formally | 1015 // this commit. We do this now because the navigation hasn't formally |
| 994 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1016 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 995 // this triggers won't be able to figure out what's going on. | 1017 // this triggers won't be able to figure out what's going on. |
| 996 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1018 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 997 | 1019 |
| 998 // We expect SwapOutOldPage to have canceled any modal dialogs and told the | 1020 // 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... |
| 1098 } | 1120 } |
| 1099 | 1121 |
| 1100 // If the old RFH is live, we are swapping it out and should keep track of | 1122 // If the old RFH is live, we are swapping it out and should keep track of |
| 1101 // it in case we navigate back to it, or it is waiting for the unload event | 1123 // it in case we navigate back to it, or it is waiting for the unload event |
| 1102 // to execute in the background. | 1124 // to execute in the background. |
| 1103 // TODO(creis): Swap out the subframe in --site-per-process. | 1125 // TODO(creis): Swap out the subframe in --site-per-process. |
| 1104 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 1126 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) |
| 1105 DCHECK(old_render_frame_host->is_swapped_out() || | 1127 DCHECK(old_render_frame_host->is_swapped_out() || |
| 1106 !RenderViewHostImpl::IsRVHStateActive( | 1128 !RenderViewHostImpl::IsRVHStateActive( |
| 1107 old_render_frame_host->render_view_host()->rvh_state())); | 1129 old_render_frame_host->render_view_host()->rvh_state())); |
| 1108 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make | |
| 1109 // sure we don't get different rvh instances for the same site instance | |
| 1110 // in the same rvhmgr. | |
| 1111 // TODO(creis): Clean this up. | |
| 1112 RenderFrameProxyHostMap::iterator iter = | |
| 1113 proxy_hosts_.find(old_site_instance_id); | |
| 1114 if (iter != proxy_hosts_.end() && | |
| 1115 iter->second->render_frame_host() != old_render_frame_host) { | |
| 1116 // Delete the proxy that will be replaced in the map to avoid a leak. | |
| 1117 delete iter->second; | |
| 1118 } | |
| 1119 | 1130 |
| 1120 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, | 1131 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, |
| 1121 // the RenderFrameHost should be put in the map of RenderFrameHosts pending | 1132 // the RenderFrameHost should be put in the map of RenderFrameHosts pending |
| 1122 // shutdown. Otherwise, it is stored in the map of proxy hosts. | 1133 // shutdown. Otherwise, it is stored in the map of proxy hosts. |
| 1123 if (old_render_frame_host->render_view_host()->rvh_state() == | 1134 if (old_render_frame_host->render_view_host()->rvh_state() == |
| 1124 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { | 1135 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { |
| 1125 proxy_hosts_.erase(old_site_instance_id); | 1136 // The proxy for this RenderFrameHost is created when sending the |
| 1137 // SwapOut message, so check if it already exists and delete it. |
| 1138 RenderFrameProxyHostMap::iterator iter = |
| 1139 proxy_hosts_.find(old_site_instance_id); |
| 1140 if (iter != proxy_hosts_.end()) { |
| 1141 delete iter->second; |
| 1142 proxy_hosts_.erase(iter); |
| 1143 } |
| 1126 RFHPendingDeleteMap::iterator pending_delete_iter = | 1144 RFHPendingDeleteMap::iterator pending_delete_iter = |
| 1127 pending_delete_hosts_.find(old_site_instance_id); | 1145 pending_delete_hosts_.find(old_site_instance_id); |
| 1128 if (pending_delete_iter == pending_delete_hosts_.end() || | 1146 if (pending_delete_iter == pending_delete_hosts_.end() || |
| 1129 pending_delete_iter->second.get() != old_render_frame_host) { | 1147 pending_delete_iter->second.get() != old_render_frame_host) { |
| 1130 pending_delete_hosts_[old_site_instance_id] = | 1148 pending_delete_hosts_[old_site_instance_id] = |
| 1131 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); | 1149 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); |
| 1132 } | 1150 } |
| 1133 } else { | 1151 } else { |
| 1152 // Capture the active view count on the old RFH SiteInstance, since the |
| 1153 // ownership will be passed into the proxy and the pointer will be invalid. |
| 1154 int active_view_count = |
| 1155 static_cast<SiteInstanceImpl*>(old_render_frame_host->GetSiteInstance()) |
| 1156 ->active_view_count(); |
| 1157 |
| 1158 RenderFrameProxyHostMap::iterator iter = |
| 1159 proxy_hosts_.find(old_site_instance_id); |
| 1160 CHECK(iter != proxy_hosts_.end()); |
| 1161 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 1162 |
| 1134 // If there are no active views in this SiteInstance, it means that | 1163 // If there are no active views in this SiteInstance, it means that |
| 1135 // this RFH was the last active one in the SiteInstance. Now that we | 1164 // this RFH was the last active one in the SiteInstance. Now that we |
| 1136 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs | 1165 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs |
| 1137 // in this SiteInstance. We do this after ensuring the RFH is on the | 1166 // in this SiteInstance. |
| 1138 // swapped out list to simplify the deletion. | 1167 if (!active_view_count) |
| 1139 if (!static_cast<SiteInstanceImpl*>( | |
| 1140 old_render_frame_host->GetSiteInstance())->active_view_count()) { | |
| 1141 old_render_frame_host.reset(); | |
| 1142 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); | 1168 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); |
| 1143 } else { | |
| 1144 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost( | |
| 1145 old_render_frame_host.Pass()); | |
| 1146 } | |
| 1147 } | 1169 } |
| 1148 } | 1170 } |
| 1149 | 1171 |
| 1150 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( | 1172 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( |
| 1151 int32 site_instance_id) { | 1173 int32 site_instance_id) { |
| 1152 // First remove any swapped out RFH for this SiteInstance from our own list. | 1174 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1153 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1175 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1154 | 1176 |
| 1155 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts | 1177 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts |
| 1156 // in the SiteInstance, then tell their respective FrameTrees to remove all | 1178 // in the SiteInstance, then tell their respective FrameTrees to remove all |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1370 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 1349 | 1371 |
| 1350 // If the SiteInstance for the pending RFH is being used by others, don't | 1372 // If the SiteInstance for the pending RFH is being used by others, don't |
| 1351 // delete the RFH, just swap it out and it can be reused at a later point. | 1373 // delete the RFH, just swap it out and it can be reused at a later point. |
| 1352 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( | 1374 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( |
| 1353 pending_render_frame_host->GetSiteInstance()); | 1375 pending_render_frame_host->GetSiteInstance()); |
| 1354 if (site_instance->active_view_count() > 1) { | 1376 if (site_instance->active_view_count() > 1) { |
| 1355 // Any currently suspended navigations are no longer needed. | 1377 // Any currently suspended navigations are no longer needed. |
| 1356 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1378 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
| 1357 | 1379 |
| 1358 pending_render_frame_host->SwapOut(); | 1380 RenderFrameProxyHost* proxy = |
| 1359 | 1381 new RenderFrameProxyHost(site_instance, frame_tree_node_); |
| 1360 proxy_hosts_[site_instance->GetId()] = new RenderFrameProxyHost( | 1382 proxy_hosts_[site_instance->GetId()] = proxy; |
| 1361 pending_render_frame_host.Pass()); | 1383 pending_render_frame_host->SwapOut(proxy); |
| 1384 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); |
| 1362 } else { | 1385 } else { |
| 1363 // We won't be coming back, so delete this one. | 1386 // We won't be coming back, so delete this one. |
| 1364 pending_render_frame_host.reset(); | 1387 pending_render_frame_host.reset(); |
| 1365 } | 1388 } |
| 1366 | 1389 |
| 1367 pending_web_ui_.reset(); | 1390 pending_web_ui_.reset(); |
| 1368 pending_and_current_web_ui_.reset(); | 1391 pending_and_current_web_ui_.reset(); |
| 1369 } | 1392 } |
| 1370 | 1393 |
| 1371 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 1394 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1412 if (iter == proxy_hosts_.end()) | 1435 if (iter == proxy_hosts_.end()) |
| 1413 return false; | 1436 return false; |
| 1414 | 1437 |
| 1415 return iter->second->render_frame_host() == rfh; | 1438 return iter->second->render_frame_host() == rfh; |
| 1416 } | 1439 } |
| 1417 | 1440 |
| 1418 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( | 1441 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( |
| 1419 SiteInstance* instance) const { | 1442 SiteInstance* instance) const { |
| 1420 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1443 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1421 if (proxy) | 1444 if (proxy) |
| 1422 return proxy->render_view_host(); | 1445 return proxy->GetRenderViewHost(); |
| 1423 return NULL; | 1446 return NULL; |
| 1424 } | 1447 } |
| 1425 | 1448 |
| 1426 RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost( | 1449 RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost( |
| 1427 SiteInstance* instance) const { | 1450 SiteInstance* instance) const { |
| 1428 RenderFrameProxyHostMap::const_iterator iter = | 1451 RenderFrameProxyHostMap::const_iterator iter = |
| 1429 proxy_hosts_.find(instance->GetId()); | 1452 proxy_hosts_.find(instance->GetId()); |
| 1430 if (iter != proxy_hosts_.end()) | 1453 if (iter != proxy_hosts_.end()) |
| 1431 return iter->second; | 1454 return iter->second; |
| 1432 | 1455 |
| 1433 return NULL; | 1456 return NULL; |
| 1434 } | 1457 } |
| 1435 | 1458 |
| 1436 } // namespace content | 1459 } // namespace content |
| OLD | NEW |