| 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 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); | 538 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); |
| 539 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | 539 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
| 540 old_render_frame_host->GetSiteInstance(), frame_tree_node_); | 540 old_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 541 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) | 541 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) |
| 542 << "Inserting a duplicate item."; | 542 << "Inserting a duplicate item."; |
| 543 | 543 |
| 544 // Tell the old RenderFrameHost to swap out and be replaced by the proxy. | 544 // Tell the old RenderFrameHost to swap out and be replaced by the proxy. |
| 545 old_render_frame_host->SwapOut(proxy, true); | 545 old_render_frame_host->SwapOut(proxy, true); |
| 546 | 546 |
| 547 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 547 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 548 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) && | 548 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 549 switches::kSitePerProcess) && |
| 549 !is_main_frame) { | 550 !is_main_frame) { |
| 550 // In --site-per-process, subframes delete their RFH rather than storing it | 551 // In --site-per-process, subframes delete their RFH rather than storing it |
| 551 // in the proxy. Schedule it for deletion once the SwapOutACK comes in. | 552 // in the proxy. Schedule it for deletion once the SwapOutACK comes in. |
| 552 // TODO(creis): This will be the default when we remove swappedout://. | 553 // TODO(creis): This will be the default when we remove swappedout://. |
| 553 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); | 554 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); |
| 554 } else { | 555 } else { |
| 555 // We shouldn't get here for subframes, since we only swap subframes when | 556 // We shouldn't get here for subframes, since we only swap subframes when |
| 556 // --site-per-process is used. | 557 // --site-per-process is used. |
| 557 DCHECK(is_main_frame); | 558 DCHECK(is_main_frame); |
| 558 | 559 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } | 619 } |
| 619 | 620 |
| 620 void RenderFrameHostManager::ResetProxyHosts() { | 621 void RenderFrameHostManager::ResetProxyHosts() { |
| 621 STLDeleteValues(&proxy_hosts_); | 622 STLDeleteValues(&proxy_hosts_); |
| 622 } | 623 } |
| 623 | 624 |
| 624 // PlzNavigate | 625 // PlzNavigate |
| 625 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 626 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
| 626 const GURL& url, | 627 const GURL& url, |
| 627 ui::PageTransition transition) { | 628 ui::PageTransition transition) { |
| 628 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 629 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 629 switches::kEnableBrowserSideNavigation)); | 630 switches::kEnableBrowserSideNavigation)); |
| 630 // TODO(clamy): When we handle renderer initiated navigations, make sure not | 631 // TODO(clamy): When we handle renderer initiated navigations, make sure not |
| 631 // to use a different process for subframes if --site-per-process is not | 632 // to use a different process for subframes if --site-per-process is not |
| 632 // enabled. | 633 // enabled. |
| 633 | 634 |
| 634 // Pick the right RenderFrameHost to commit the navigation. | 635 // Pick the right RenderFrameHost to commit the navigation. |
| 635 // TODO(clamy): Replace the default values by the right ones. | 636 // TODO(clamy): Replace the default values by the right ones. |
| 636 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( | 637 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( |
| 637 url, nullptr, nullptr, transition, false, false, GlobalRequestID(), | 638 url, nullptr, nullptr, transition, false, false, GlobalRequestID(), |
| 638 NavigationEntryImpl::kInvalidBindings); | 639 NavigationEntryImpl::kInvalidBindings); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 } | 706 } |
| 706 | 707 |
| 707 return true; | 708 return true; |
| 708 } | 709 } |
| 709 | 710 |
| 710 bool RenderFrameHostManager::ShouldTransitionCrossSite() { | 711 bool RenderFrameHostManager::ShouldTransitionCrossSite() { |
| 711 // False in the single-process mode, as it makes RVHs to accumulate | 712 // False in the single-process mode, as it makes RVHs to accumulate |
| 712 // in swapped_out_hosts_. | 713 // in swapped_out_hosts_. |
| 713 // True if we are using process-per-site-instance (default) or | 714 // True if we are using process-per-site-instance (default) or |
| 714 // process-per-site (kProcessPerSite). | 715 // process-per-site (kProcessPerSite). |
| 715 return | 716 return !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 716 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) && | 717 switches::kSingleProcess) && |
| 717 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); | 718 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 719 switches::kProcessPerTab); |
| 718 } | 720 } |
| 719 | 721 |
| 720 bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation( | 722 bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation( |
| 721 const GURL& current_effective_url, | 723 const GURL& current_effective_url, |
| 722 bool current_is_view_source_mode, | 724 bool current_is_view_source_mode, |
| 723 SiteInstance* new_site_instance, | 725 SiteInstance* new_site_instance, |
| 724 const GURL& new_effective_url, | 726 const GURL& new_effective_url, |
| 725 bool new_is_view_source_mode) const { | 727 bool new_is_view_source_mode) const { |
| 726 // If new_entry already has a SiteInstance, assume it is correct. We only | 728 // If new_entry already has a SiteInstance, assume it is correct. We only |
| 727 // need to force a swap if it is in a different BrowsingInstance. | 729 // need to force a swap if it is in a different BrowsingInstance. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 // (UGLY) HEURISTIC, process-per-site only: | 875 // (UGLY) HEURISTIC, process-per-site only: |
| 874 // | 876 // |
| 875 // If this navigation is generated, then it probably corresponds to a search | 877 // If this navigation is generated, then it probably corresponds to a search |
| 876 // query. Given that search results typically lead to users navigating to | 878 // query. Given that search results typically lead to users navigating to |
| 877 // other sites, we don't really want to use the search engine hostname to | 879 // other sites, we don't really want to use the search engine hostname to |
| 878 // determine the site instance for this navigation. | 880 // determine the site instance for this navigation. |
| 879 // | 881 // |
| 880 // NOTE: This can be removed once we have a way to transition between | 882 // NOTE: This can be removed once we have a way to transition between |
| 881 // RenderViews in response to a link click. | 883 // RenderViews in response to a link click. |
| 882 // | 884 // |
| 883 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && | 885 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 884 ui::PageTransitionCoreTypeIs( | 886 switches::kProcessPerSite) && |
| 885 transition, ui::PAGE_TRANSITION_GENERATED)) { | 887 ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED)) { |
| 886 return current_instance; | 888 return current_instance; |
| 887 } | 889 } |
| 888 | 890 |
| 889 SiteInstanceImpl* current_site_instance = | 891 SiteInstanceImpl* current_site_instance = |
| 890 static_cast<SiteInstanceImpl*>(current_instance); | 892 static_cast<SiteInstanceImpl*>(current_instance); |
| 891 | 893 |
| 892 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it | 894 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it |
| 893 // for this entry. We won't commit the SiteInstance to this site until the | 895 // for this entry. We won't commit the SiteInstance to this site until the |
| 894 // navigation commits (in DidNavigate), unless the navigation entry was | 896 // navigation commits (in DidNavigate), unless the navigation entry was |
| 895 // restored or it's a Web UI as described below. | 897 // restored or it's a Web UI as described below. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1014 |
| 1013 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( | 1015 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( |
| 1014 SiteInstance* current_instance, NavigationEntry* current_entry) { | 1016 SiteInstance* current_instance, NavigationEntry* current_entry) { |
| 1015 // If this is a subframe that is potentially out of process from its parent, | 1017 // If this is a subframe that is potentially out of process from its parent, |
| 1016 // don't consider using current_entry's url for SiteInstance selection, since | 1018 // don't consider using current_entry's url for SiteInstance selection, since |
| 1017 // current_entry's url is for the main frame and may be in a different site | 1019 // current_entry's url is for the main frame and may be in a different site |
| 1018 // than this frame. | 1020 // than this frame. |
| 1019 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. | 1021 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. |
| 1020 // See http://crbug.com/369654 | 1022 // See http://crbug.com/369654 |
| 1021 if (!frame_tree_node_->IsMainFrame() && | 1023 if (!frame_tree_node_->IsMainFrame() && |
| 1022 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 1024 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1025 switches::kSitePerProcess)) |
| 1023 return frame_tree_node_->current_url(); | 1026 return frame_tree_node_->current_url(); |
| 1024 | 1027 |
| 1025 // If there is no last non-interstitial entry (and current_instance already | 1028 // If there is no last non-interstitial entry (and current_instance already |
| 1026 // has a site), then we must have been opened from another tab. We want | 1029 // has a site), then we must have been opened from another tab. We want |
| 1027 // to compare against the URL of the page that opened us, but we can't | 1030 // to compare against the URL of the page that opened us, but we can't |
| 1028 // get to it directly. The best we can do is check against the site of | 1031 // get to it directly. The best we can do is check against the site of |
| 1029 // the SiteInstance. This will be correct when we intercept links and | 1032 // the SiteInstance. This will be correct when we intercept links and |
| 1030 // script-based navigations, but for now, it could place some pages in a | 1033 // script-based navigations, but for now, it could place some pages in a |
| 1031 // new process unnecessarily. We should only hit this case if a page tries | 1034 // new process unnecessarily. We should only hit this case if a page tries |
| 1032 // to open a new tab to an interstitial-inducing URL, and then navigates | 1035 // to open a new tab to an interstitial-inducing URL, and then navigates |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1060 create_render_frame_flags, nullptr); | 1063 create_render_frame_flags, nullptr); |
| 1061 } | 1064 } |
| 1062 | 1065 |
| 1063 int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded( | 1066 int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded( |
| 1064 SiteInstance* old_instance, | 1067 SiteInstance* old_instance, |
| 1065 SiteInstance* new_instance) { | 1068 SiteInstance* new_instance) { |
| 1066 int opener_route_id = MSG_ROUTING_NONE; | 1069 int opener_route_id = MSG_ROUTING_NONE; |
| 1067 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1070 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
| 1068 opener_route_id = | 1071 opener_route_id = |
| 1069 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | 1072 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); |
| 1070 if (CommandLine::ForCurrentProcess()->HasSwitch( | 1073 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1071 switches::kSitePerProcess)) { | 1074 switches::kSitePerProcess)) { |
| 1072 // Ensure that the frame tree has RenderFrameProxyHosts for the new | 1075 // Ensure that the frame tree has RenderFrameProxyHosts for the new |
| 1073 // SiteInstance in all nodes except the current one. | 1076 // SiteInstance in all nodes except the current one. |
| 1074 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | 1077 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( |
| 1075 frame_tree_node_, new_instance); | 1078 frame_tree_node_, new_instance); |
| 1076 } | 1079 } |
| 1077 } | 1080 } |
| 1078 return opener_route_id; | 1081 return opener_route_id; |
| 1079 } | 1082 } |
| 1080 | 1083 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); | 1397 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); |
| 1395 | 1398 |
| 1396 // Swap out the old frame now that the new one is visible. | 1399 // Swap out the old frame now that the new one is visible. |
| 1397 // This will swap it out and then put it on the proxy list (if there are other | 1400 // This will swap it out and then put it on the proxy list (if there are other |
| 1398 // active views in its SiteInstance) or schedule it for deletion when the swap | 1401 // active views in its SiteInstance) or schedule it for deletion when the swap |
| 1399 // out ack arrives (or immediately if the process isn't live). | 1402 // out ack arrives (or immediately if the process isn't live). |
| 1400 // In the --site-per-process case, old subframe RHFs are not kept alive inside | 1403 // In the --site-per-process case, old subframe RHFs are not kept alive inside |
| 1401 // the proxy. | 1404 // the proxy. |
| 1402 SwapOutOldFrame(old_render_frame_host.Pass()); | 1405 SwapOutOldFrame(old_render_frame_host.Pass()); |
| 1403 | 1406 |
| 1404 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) && | 1407 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1408 switches::kSitePerProcess) && |
| 1405 !is_main_frame) { | 1409 !is_main_frame) { |
| 1406 // If this is a subframe, it should have a CrossProcessFrameConnector | 1410 // If this is a subframe, it should have a CrossProcessFrameConnector |
| 1407 // created already. Use it to link the new RFH's view to the proxy that | 1411 // created already. Use it to link the new RFH's view to the proxy that |
| 1408 // belongs to the parent frame's SiteInstance. | 1412 // belongs to the parent frame's SiteInstance. |
| 1409 // Note: We do this after swapping out the old RFH because that may create | 1413 // Note: We do this after swapping out the old RFH because that may create |
| 1410 // the proxy we're looking for. | 1414 // the proxy we're looking for. |
| 1411 RenderFrameProxyHost* proxy_to_parent = GetProxyToParent(); | 1415 RenderFrameProxyHost* proxy_to_parent = GetProxyToParent(); |
| 1412 if (proxy_to_parent) { | 1416 if (proxy_to_parent) { |
| 1413 proxy_to_parent->SetChildRWHView( | 1417 proxy_to_parent->SetChildRWHView( |
| 1414 render_frame_host_->render_view_host()->GetView()); | 1418 render_frame_host_->render_view_host()->GetView()); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 } | 1528 } |
| 1525 // Otherwise, it's safe to treat this as a pending cross-site transition. | 1529 // Otherwise, it's safe to treat this as a pending cross-site transition. |
| 1526 | 1530 |
| 1527 // We now have a pending RFH. | 1531 // We now have a pending RFH. |
| 1528 DCHECK(!cross_navigation_pending_); | 1532 DCHECK(!cross_navigation_pending_); |
| 1529 cross_navigation_pending_ = true; | 1533 cross_navigation_pending_ = true; |
| 1530 | 1534 |
| 1531 // PlzNavigate: There is no notion of transfer navigations, and the old | 1535 // PlzNavigate: There is no notion of transfer navigations, and the old |
| 1532 // renderer before unload handler has already run at that point, so return | 1536 // renderer before unload handler has already run at that point, so return |
| 1533 // here. | 1537 // here. |
| 1534 if (CommandLine::ForCurrentProcess()->HasSwitch( | 1538 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1535 switches::kEnableBrowserSideNavigation)) { | 1539 switches::kEnableBrowserSideNavigation)) { |
| 1536 return pending_render_frame_host_.get(); | 1540 return pending_render_frame_host_.get(); |
| 1537 } | 1541 } |
| 1538 | 1542 |
| 1539 // We need to wait until the beforeunload handler has run, unless we are | 1543 // We need to wait until the beforeunload handler has run, unless we are |
| 1540 // transferring an existing request (in which case it has already run). | 1544 // transferring an existing request (in which case it has already run). |
| 1541 // Suspend the new render view (i.e., don't let it send the cross-site | 1545 // Suspend the new render view (i.e., don't let it send the cross-site |
| 1542 // Navigate message) until we hear back from the old renderer's | 1546 // Navigate message) until we hear back from the old renderer's |
| 1543 // beforeunload handler. If the handler returns false, we'll have to | 1547 // beforeunload handler. If the handler returns false, we'll have to |
| 1544 // cancel the request. | 1548 // cancel the request. |
| 1545 // | 1549 // |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1707 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 1704 SiteInstance* instance) { | 1708 SiteInstance* instance) { |
| 1705 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1709 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 1706 if (iter != proxy_hosts_.end()) { | 1710 if (iter != proxy_hosts_.end()) { |
| 1707 delete iter->second; | 1711 delete iter->second; |
| 1708 proxy_hosts_.erase(iter); | 1712 proxy_hosts_.erase(iter); |
| 1709 } | 1713 } |
| 1710 } | 1714 } |
| 1711 | 1715 |
| 1712 } // namespace content | 1716 } // namespace content |
| OLD | NEW |