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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
639 // in swapped_out_hosts_. | 639 // in swapped_out_hosts_. |
640 // True if we are using process-per-site-instance (default) or | 640 // True if we are using process-per-site-instance (default) or |
641 // process-per-site (kProcessPerSite). | 641 // process-per-site (kProcessPerSite). |
642 return | 642 return |
643 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) && | 643 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) && |
644 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); | 644 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); |
645 } | 645 } |
646 | 646 |
647 bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation( | 647 bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation( |
648 const NavigationEntry* current_entry, | 648 const NavigationEntry* current_entry, |
649 const NavigationEntryImpl* new_entry) const { | 649 SiteInstance* new_site_instance, |
650 DCHECK(new_entry); | 650 const GURL& new_url, |
651 | 651 bool new_is_view_source_mode) const { |
652 // If new_entry already has a SiteInstance, assume it is correct. We only | 652 // If new_entry already has a SiteInstance, assume it is correct. We only |
653 // need to force a swap if it is in a different BrowsingInstance. | 653 // need to force a swap if it is in a different BrowsingInstance. |
654 if (new_entry->site_instance()) { | 654 if (new_site_instance) { |
655 return !new_entry->site_instance()->IsRelatedSiteInstance( | 655 return !new_site_instance->IsRelatedSiteInstance( |
656 render_frame_host_->GetSiteInstance()); | 656 render_frame_host_->GetSiteInstance()); |
657 } | 657 } |
658 | 658 |
659 // Check for reasons to swap processes even if we are in a process model that | 659 // Check for reasons to swap processes even if we are in a process model that |
660 // doesn't usually swap (e.g., process-per-tab). Any time we return true, | 660 // doesn't usually swap (e.g., process-per-tab). Any time we return true, |
661 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance. | 661 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance. |
662 | 662 |
663 // We use the effective URL here, since that's what is used in the | 663 // We use the effective URL here, since that's what is used in the |
664 // SiteInstance's site and when we later call IsSameWebSite. If there is no | 664 // SiteInstance's site and when we later call IsSameWebSite. If there is no |
665 // current_entry, check the current SiteInstance's site, which might already | 665 // current_entry, check the current SiteInstance's site, which might already |
666 // be committed to a Web UI URL (such as the NTP). | 666 // be committed to a Web UI URL (such as the NTP). |
667 BrowserContext* browser_context = | 667 BrowserContext* browser_context = |
668 delegate_->GetControllerForRenderManager().GetBrowserContext(); | 668 delegate_->GetControllerForRenderManager().GetBrowserContext(); |
669 const GURL& current_url = (current_entry) ? | 669 const GURL& current_url = (current_entry) ? |
670 SiteInstanceImpl::GetEffectiveURL(browser_context, | 670 SiteInstanceImpl::GetEffectiveURL(browser_context, |
671 current_entry->GetURL()) : | 671 current_entry->GetURL()) : |
672 render_frame_host_->GetSiteInstance()->GetSiteURL(); | 672 render_frame_host_->GetSiteInstance()->GetSiteURL(); |
673 const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context, | |
674 new_entry->GetURL()); | |
675 | 673 |
676 // Don't force a new BrowsingInstance for debug URLs that are handled in the | 674 // Don't force a new BrowsingInstance for debug URLs that are handled in the |
677 // renderer process, like javascript: or chrome://crash. | 675 // renderer process, like javascript: or chrome://crash. |
678 if (IsRendererDebugURL(new_url)) | 676 if (IsRendererDebugURL(new_url)) |
679 return false; | 677 return false; |
680 | 678 |
681 // For security, we should transition between processes when one is a Web UI | 679 // For security, we should transition between processes when one is a Web UI |
682 // page and one isn't. | 680 // page and one isn't. |
683 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( | 681 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( |
684 browser_context, current_url)) { | 682 browser_context, current_url)) { |
(...skipping 17 matching lines...) Expand all Loading... | |
702 render_frame_host_->GetSiteInstance(), | 700 render_frame_host_->GetSiteInstance(), |
703 current_url, new_url)) { | 701 current_url, new_url)) { |
704 return true; | 702 return true; |
705 } | 703 } |
706 | 704 |
707 // We can't switch a RenderView between view source and non-view source mode | 705 // We can't switch a RenderView between view source and non-view source mode |
708 // without screwing up the session history sometimes (when navigating between | 706 // without screwing up the session history sometimes (when navigating between |
709 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat | 707 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat |
710 // it as a new navigation). So require a BrowsingInstance switch. | 708 // it as a new navigation). So require a BrowsingInstance switch. |
711 if (current_entry && | 709 if (current_entry && |
712 current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) | 710 current_entry->IsViewSourceMode() != new_is_view_source_mode) |
713 return true; | 711 return true; |
714 | 712 |
715 return false; | 713 return false; |
716 } | 714 } |
717 | 715 |
718 bool RenderFrameHostManager::ShouldReuseWebUI( | 716 bool RenderFrameHostManager::ShouldReuseWebUI( |
719 const NavigationEntry* current_entry, | 717 const NavigationEntry* current_entry, |
720 const NavigationEntryImpl* new_entry) const { | 718 const NavigationEntryImpl* new_entry) const { |
721 NavigationControllerImpl& controller = | 719 NavigationControllerImpl& controller = |
722 delegate_->GetControllerForRenderManager(); | 720 delegate_->GetControllerForRenderManager(); |
723 return current_entry && web_ui_.get() && | 721 return current_entry && web_ui_.get() && |
724 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 722 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
725 controller.GetBrowserContext(), current_entry->GetURL()) == | 723 controller.GetBrowserContext(), current_entry->GetURL()) == |
726 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 724 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
727 controller.GetBrowserContext(), new_entry->GetURL())); | 725 controller.GetBrowserContext(), new_entry->GetURL())); |
728 } | 726 } |
729 | 727 |
730 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry( | 728 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( |
731 const NavigationEntryImpl& entry, | 729 const GURL& dest_url, |
730 SiteInstance* navigation_instance, | |
732 SiteInstance* current_instance, | 731 SiteInstance* current_instance, |
733 bool force_browsing_instance_swap) { | 732 PageTransition page_transition, |
734 // Determine which SiteInstance to use for navigating to |entry|. | 733 NavigationEntryImpl::RestoreType restore_type, |
735 const GURL& dest_url = entry.GetURL(); | 734 bool force_browsing_instance_swap, |
735 bool is_view_source_mode) { | |
736 NavigationControllerImpl& controller = | 736 NavigationControllerImpl& controller = |
737 delegate_->GetControllerForRenderManager(); | 737 delegate_->GetControllerForRenderManager(); |
738 BrowserContext* browser_context = controller.GetBrowserContext(); | 738 BrowserContext* browser_context = controller.GetBrowserContext(); |
739 | 739 |
740 // If the entry has an instance already we should use it. | 740 // If the entry has an instance already we should use it. |
741 if (entry.site_instance()) { | 741 if (navigation_instance) { |
742 // If we are forcing a swap, this should be in a different BrowsingInstance. | 742 // If we are forcing a swap, this should be in a different BrowsingInstance. |
743 if (force_browsing_instance_swap) { | 743 if (force_browsing_instance_swap) { |
744 CHECK(!entry.site_instance()->IsRelatedSiteInstance( | 744 CHECK(!navigation_instance->IsRelatedSiteInstance( |
745 render_frame_host_->GetSiteInstance())); | 745 render_frame_host_->GetSiteInstance())); |
746 } | 746 } |
747 return entry.site_instance(); | 747 return navigation_instance; |
748 } | 748 } |
749 | 749 |
750 // If a swap is required, we need to force the SiteInstance AND | 750 // If a swap is required, we need to force the SiteInstance AND |
751 // BrowsingInstance to be different ones, using CreateForURL. | 751 // BrowsingInstance to be different ones, using CreateForURL. |
752 if (force_browsing_instance_swap) | 752 if (force_browsing_instance_swap) |
753 return SiteInstance::CreateForURL(browser_context, dest_url); | 753 return SiteInstance::CreateForURL(browser_context, dest_url); |
754 | 754 |
755 // (UGLY) HEURISTIC, process-per-site only: | 755 // (UGLY) HEURISTIC, process-per-site only: |
756 // | 756 // |
757 // If this navigation is generated, then it probably corresponds to a search | 757 // If this navigation is generated, then it probably corresponds to a search |
758 // query. Given that search results typically lead to users navigating to | 758 // query. Given that search results typically lead to users navigating to |
759 // other sites, we don't really want to use the search engine hostname to | 759 // other sites, we don't really want to use the search engine hostname to |
760 // determine the site instance for this navigation. | 760 // determine the site instance for this navigation. |
761 // | 761 // |
762 // NOTE: This can be removed once we have a way to transition between | 762 // NOTE: This can be removed once we have a way to transition between |
763 // RenderViews in response to a link click. | 763 // RenderViews in response to a link click. |
764 // | 764 // |
765 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && | 765 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && |
766 PageTransitionCoreTypeIs(entry.GetTransitionType(), | 766 PageTransitionCoreTypeIs(page_transition, PAGE_TRANSITION_GENERATED)) { |
767 PAGE_TRANSITION_GENERATED)) { | |
768 return current_instance; | 767 return current_instance; |
769 } | 768 } |
770 | 769 |
771 SiteInstanceImpl* current_site_instance = | 770 SiteInstanceImpl* current_site_instance = |
772 static_cast<SiteInstanceImpl*>(current_instance); | 771 static_cast<SiteInstanceImpl*>(current_instance); |
773 | 772 |
774 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it | 773 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it |
775 // for this entry. We won't commit the SiteInstance to this site until the | 774 // for this entry. We won't commit the SiteInstance to this site until the |
776 // navigation commits (in DidNavigate), unless the navigation entry was | 775 // navigation commits (in DidNavigate), unless the navigation entry was |
777 // restored or it's a Web UI as described below. | 776 // restored or it's a Web UI as described below. |
(...skipping 21 matching lines...) Expand all Loading... | |
799 // not want to use the current_instance if it has no site, since it will | 798 // not want to use the current_instance if it has no site, since it will |
800 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for | 799 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for |
801 // this URL instead (with the correct process type). | 800 // this URL instead (with the correct process type). |
802 if (current_site_instance->HasWrongProcessForURL(dest_url)) | 801 if (current_site_instance->HasWrongProcessForURL(dest_url)) |
803 return current_site_instance->GetRelatedSiteInstance(dest_url); | 802 return current_site_instance->GetRelatedSiteInstance(dest_url); |
804 | 803 |
805 // View-source URLs must use a new SiteInstance and BrowsingInstance. | 804 // View-source URLs must use a new SiteInstance and BrowsingInstance. |
806 // TODO(nasko): This is the same condition as later in the function. This | 805 // TODO(nasko): This is the same condition as later in the function. This |
807 // should be taken into account when refactoring this method as part of | 806 // should be taken into account when refactoring this method as part of |
808 // http://crbug.com/123007. | 807 // http://crbug.com/123007. |
809 if (entry.IsViewSourceMode()) | 808 if (is_view_source_mode) |
810 return SiteInstance::CreateForURL(browser_context, dest_url); | 809 return SiteInstance::CreateForURL(browser_context, dest_url); |
811 | 810 |
812 // If we are navigating from a blank SiteInstance to a WebUI, make sure we | 811 // If we are navigating from a blank SiteInstance to a WebUI, make sure we |
813 // create a new SiteInstance. | 812 // create a new SiteInstance. |
814 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( | 813 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( |
815 browser_context, dest_url)) { | 814 browser_context, dest_url)) { |
816 return SiteInstance::CreateForURL(browser_context, dest_url); | 815 return SiteInstance::CreateForURL(browser_context, dest_url); |
817 } | 816 } |
818 | 817 |
819 // Normally the "site" on the SiteInstance is set lazily when the load | 818 // Normally the "site" on the SiteInstance is set lazily when the load |
820 // actually commits. This is to support better process sharing in case | 819 // actually commits. This is to support better process sharing in case |
821 // the site redirects to some other site: we want to use the destination | 820 // the site redirects to some other site: we want to use the destination |
822 // site in the site instance. | 821 // site in the site instance. |
823 // | 822 // |
824 // In the case of session restore, as it loads all the pages immediately | 823 // In the case of session restore, as it loads all the pages immediately |
825 // we need to set the site first, otherwise after a restore none of the | 824 // we need to set the site first, otherwise after a restore none of the |
826 // pages would share renderers in process-per-site. | 825 // pages would share renderers in process-per-site. |
827 // | 826 // |
828 // The embedder can request some urls never to be assigned to SiteInstance | 827 // The embedder can request some urls never to be assigned to SiteInstance |
829 // through the ShouldAssignSiteForURL() content client method, so that | 828 // through the ShouldAssignSiteForURL() content client method, so that |
830 // renderers created for particular chrome urls (e.g. the chrome-native:// | 829 // renderers created for particular chrome urls (e.g. the chrome-native:// |
831 // scheme) can be reused for subsequent navigations in the same WebContents. | 830 // scheme) can be reused for subsequent navigations in the same WebContents. |
832 // See http://crbug.com/386542. | 831 // See http://crbug.com/386542. |
833 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE && | 832 if (restore_type != NavigationEntryImpl::RESTORE_NONE && |
834 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { | 833 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { |
835 current_site_instance->SetSite(dest_url); | 834 current_site_instance->SetSite(dest_url); |
836 } | 835 } |
837 | 836 |
838 return current_site_instance; | 837 return current_site_instance; |
839 } | 838 } |
840 | 839 |
841 // Otherwise, only create a new SiteInstance for a cross-site navigation. | 840 // Otherwise, only create a new SiteInstance for a cross-site navigation. |
842 | 841 |
843 // TODO(creis): Once we intercept links and script-based navigations, we | 842 // TODO(creis): Once we intercept links and script-based navigations, we |
(...skipping 22 matching lines...) Expand all Loading... | |
866 // practice.) | 865 // practice.) |
867 const GURL& current_url = (current_entry) ? current_entry->GetURL() : | 866 const GURL& current_url = (current_entry) ? current_entry->GetURL() : |
868 current_instance->GetSiteURL(); | 867 current_instance->GetSiteURL(); |
869 | 868 |
870 // View-source URLs must use a new SiteInstance and BrowsingInstance. | 869 // View-source URLs must use a new SiteInstance and BrowsingInstance. |
871 // We don't need a swap when going from view-source to a debug URL like | 870 // We don't need a swap when going from view-source to a debug URL like |
872 // chrome://crash, however. | 871 // chrome://crash, however. |
873 // TODO(creis): Refactor this method so this duplicated code isn't needed. | 872 // TODO(creis): Refactor this method so this duplicated code isn't needed. |
874 // See http://crbug.com/123007. | 873 // See http://crbug.com/123007. |
875 if (current_entry && | 874 if (current_entry && |
876 current_entry->IsViewSourceMode() != entry.IsViewSourceMode() && | 875 current_entry->IsViewSourceMode() != is_view_source_mode && |
877 !IsRendererDebugURL(dest_url)) { | 876 !IsRendererDebugURL(dest_url)) { |
878 return SiteInstance::CreateForURL(browser_context, dest_url); | 877 return SiteInstance::CreateForURL(browser_context, dest_url); |
879 } | 878 } |
880 | 879 |
881 // Use the current SiteInstance for same site navigations, as long as the | 880 // Use the current SiteInstance for same site navigations, as long as the |
882 // process type is correct. (The URL may have been installed as an app since | 881 // process type is correct. (The URL may have been installed as an app since |
883 // the last time we visited it.) | 882 // the last time we visited it.) |
884 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && | 883 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && |
885 !current_site_instance->HasWrongProcessForURL(dest_url)) { | 884 !current_site_instance->HasWrongProcessForURL(dest_url)) { |
886 return current_instance; | 885 return current_instance; |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1325 // We do not currently swap processes for navigations in webview tag guests. | 1324 // We do not currently swap processes for navigations in webview tag guests. |
1326 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); | 1325 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); |
1327 | 1326 |
1328 // Determine if we need a new BrowsingInstance for this entry. If true, this | 1327 // Determine if we need a new BrowsingInstance for this entry. If true, this |
1329 // implies that it will get a new SiteInstance (and likely process), and that | 1328 // implies that it will get a new SiteInstance (and likely process), and that |
1330 // other tabs in the current BrowsingInstance will be unable to script it. | 1329 // other tabs in the current BrowsingInstance will be unable to script it. |
1331 // This is used for cases that require a process swap even in the | 1330 // This is used for cases that require a process swap even in the |
1332 // process-per-tab model, such as WebUI pages. | 1331 // process-per-tab model, such as WebUI pages. |
1333 const NavigationEntry* current_entry = | 1332 const NavigationEntry* current_entry = |
1334 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1333 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
1334 BrowserContext* browser_context = | |
1335 delegate_->GetControllerForRenderManager().GetBrowserContext(); | |
1335 bool force_swap = !is_guest_scheme && | 1336 bool force_swap = !is_guest_scheme && |
1336 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry); | 1337 ShouldSwapBrowsingInstancesForNavigation( |
1338 current_entry, | |
1339 entry.site_instance(), | |
1340 SiteInstanceImpl::GetEffectiveURL(browser_context, entry.GetURL()), | |
1341 entry.IsViewSourceMode()); | |
1337 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) | 1342 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) |
Charlie Reis
2014/08/14 06:28:08
This needs braces if the body is more than one lin
clamy
2014/08/14 10:02:59
Done.
| |
1338 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap); | 1343 new_instance = GetSiteInstanceForURL( |
1344 entry.GetURL(), | |
1345 entry.site_instance(), | |
1346 current_instance, | |
1347 entry.GetTransitionType(), | |
1348 entry.restore_type(), | |
1349 force_swap, | |
1350 entry.IsViewSourceMode()); | |
1339 | 1351 |
1340 // If force_swap is true, we must use a different SiteInstance. If we didn't, | 1352 // If force_swap is true, we must use a different SiteInstance. If we didn't, |
1341 // we would have two RenderFrameHosts in the same SiteInstance and the same | 1353 // we would have two RenderFrameHosts in the same SiteInstance and the same |
1342 // frame, resulting in page_id conflicts for their NavigationEntries. | 1354 // frame, resulting in page_id conflicts for their NavigationEntries. |
1343 if (force_swap) | 1355 if (force_swap) |
1344 CHECK_NE(new_instance, current_instance); | 1356 CHECK_NE(new_instance, current_instance); |
1345 | 1357 |
1346 if (new_instance != current_instance) { | 1358 if (new_instance != current_instance) { |
1347 // New SiteInstance: create a pending RFH to navigate. | 1359 // New SiteInstance: create a pending RFH to navigate. |
1348 DCHECK(!cross_navigation_pending_); | 1360 DCHECK(!cross_navigation_pending_); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1590 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1602 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
1591 SiteInstance* instance) { | 1603 SiteInstance* instance) { |
1592 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1604 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
1593 if (iter != proxy_hosts_.end()) { | 1605 if (iter != proxy_hosts_.end()) { |
1594 delete iter->second; | 1606 delete iter->second; |
1595 proxy_hosts_.erase(iter); | 1607 proxy_hosts_.erase(iter); |
1596 } | 1608 } |
1597 } | 1609 } |
1598 | 1610 |
1599 } // namespace content | 1611 } // namespace content |
OLD | NEW |