Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 471603002: Remove dependency on NavigationEntry to get a SiteInstance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // False in the single-process mode, as it makes RVHs to accumulate 638 // False in the single-process mode, as it makes RVHs to accumulate
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 GURL& current_effective_url,
649 const NavigationEntryImpl* new_entry) const { 649 bool current_is_view_source_mode,
650 DCHECK(new_entry); 650 SiteInstance* new_site_instance,
651 651 const GURL& new_effective_url,
652 bool new_is_view_source_mode) const {
652 // If new_entry already has a SiteInstance, assume it is correct. We only 653 // 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. 654 // need to force a swap if it is in a different BrowsingInstance.
654 if (new_entry->site_instance()) { 655 if (new_site_instance) {
655 return !new_entry->site_instance()->IsRelatedSiteInstance( 656 return !new_site_instance->IsRelatedSiteInstance(
656 render_frame_host_->GetSiteInstance()); 657 render_frame_host_->GetSiteInstance());
657 } 658 }
658 659
659 // Check for reasons to swap processes even if we are in a process model that 660 // 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, 661 // 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. 662 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance.
662
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
665 // current_entry, check the current SiteInstance's site, which might already
666 // be committed to a Web UI URL (such as the NTP).
667 BrowserContext* browser_context = 663 BrowserContext* browser_context =
668 delegate_->GetControllerForRenderManager().GetBrowserContext(); 664 delegate_->GetControllerForRenderManager().GetBrowserContext();
669 const GURL& current_url = (current_entry) ?
670 SiteInstanceImpl::GetEffectiveURL(browser_context,
671 current_entry->GetURL()) :
672 render_frame_host_->GetSiteInstance()->GetSiteURL();
673 const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
674 new_entry->GetURL());
675 665
676 // Don't force a new BrowsingInstance for debug URLs that are handled in the 666 // Don't force a new BrowsingInstance for debug URLs that are handled in the
677 // renderer process, like javascript: or chrome://crash. 667 // renderer process, like javascript: or chrome://crash.
678 if (IsRendererDebugURL(new_url)) 668 if (IsRendererDebugURL(new_effective_url))
679 return false; 669 return false;
680 670
681 // For security, we should transition between processes when one is a Web UI 671 // For security, we should transition between processes when one is a Web UI
682 // page and one isn't. 672 // page and one isn't.
683 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 673 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
684 browser_context, current_url)) { 674 browser_context, current_effective_url)) {
685 // If so, force a swap if destination is not an acceptable URL for Web UI. 675 // If so, force a swap if destination is not an acceptable URL for Web UI.
686 // Here, data URLs are never allowed. 676 // Here, data URLs are never allowed.
687 if (!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( 677 if (!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
688 browser_context, new_url)) { 678 browser_context, new_effective_url)) {
689 return true; 679 return true;
690 } 680 }
691 } else { 681 } else {
692 // Force a swap if it's a Web UI URL. 682 // Force a swap if it's a Web UI URL.
693 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 683 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
694 browser_context, new_url)) { 684 browser_context, new_effective_url)) {
695 return true; 685 return true;
696 } 686 }
697 } 687 }
698 688
699 // Check with the content client as well. Important to pass current_url here, 689 // Check with the content client as well. Important to pass
700 // which uses the SiteInstance's site if there is no current_entry. 690 // current_effective_url here, which uses the SiteInstance's site if there is
691 // no current_entry.
701 if (GetContentClient()->browser()->ShouldSwapBrowsingInstancesForNavigation( 692 if (GetContentClient()->browser()->ShouldSwapBrowsingInstancesForNavigation(
702 render_frame_host_->GetSiteInstance(), 693 render_frame_host_->GetSiteInstance(),
703 current_url, new_url)) { 694 current_effective_url, new_effective_url)) {
704 return true; 695 return true;
705 } 696 }
706 697
707 // We can't switch a RenderView between view source and non-view source mode 698 // 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 699 // without screwing up the session history sometimes (when navigating between
709 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat 700 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat
710 // it as a new navigation). So require a BrowsingInstance switch. 701 // it as a new navigation). So require a BrowsingInstance switch.
711 if (current_entry && 702 if (current_is_view_source_mode != new_is_view_source_mode)
712 current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
713 return true; 703 return true;
714 704
715 return false; 705 return false;
716 } 706 }
717 707
718 bool RenderFrameHostManager::ShouldReuseWebUI( 708 bool RenderFrameHostManager::ShouldReuseWebUI(
719 const NavigationEntry* current_entry, 709 const NavigationEntry* current_entry,
720 const NavigationEntryImpl* new_entry) const { 710 const NavigationEntryImpl* new_entry) const {
721 NavigationControllerImpl& controller = 711 NavigationControllerImpl& controller =
722 delegate_->GetControllerForRenderManager(); 712 delegate_->GetControllerForRenderManager();
723 return current_entry && web_ui_.get() && 713 return current_entry && web_ui_.get() &&
724 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 714 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
725 controller.GetBrowserContext(), current_entry->GetURL()) == 715 controller.GetBrowserContext(), current_entry->GetURL()) ==
726 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 716 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
727 controller.GetBrowserContext(), new_entry->GetURL())); 717 controller.GetBrowserContext(), new_entry->GetURL()));
728 } 718 }
729 719
730 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry( 720 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL(
731 const NavigationEntryImpl& entry, 721 const GURL& dest_url,
722 SiteInstance* dest_instance,
723 PageTransition dest_transition,
724 bool dest_is_restore,
725 bool dest_is_view_source_mode,
732 SiteInstance* current_instance, 726 SiteInstance* current_instance,
733 bool force_browsing_instance_swap) { 727 bool force_browsing_instance_swap) {
734 // Determine which SiteInstance to use for navigating to |entry|.
735 const GURL& dest_url = entry.GetURL();
736 NavigationControllerImpl& controller = 728 NavigationControllerImpl& controller =
737 delegate_->GetControllerForRenderManager(); 729 delegate_->GetControllerForRenderManager();
738 BrowserContext* browser_context = controller.GetBrowserContext(); 730 BrowserContext* browser_context = controller.GetBrowserContext();
739 731
740 // If the entry has an instance already we should use it. 732 // If the entry has an instance already we should use it.
741 if (entry.site_instance()) { 733 if (dest_instance) {
742 // If we are forcing a swap, this should be in a different BrowsingInstance. 734 // If we are forcing a swap, this should be in a different BrowsingInstance.
743 if (force_browsing_instance_swap) { 735 if (force_browsing_instance_swap) {
744 CHECK(!entry.site_instance()->IsRelatedSiteInstance( 736 CHECK(!dest_instance->IsRelatedSiteInstance(
745 render_frame_host_->GetSiteInstance())); 737 render_frame_host_->GetSiteInstance()));
746 } 738 }
747 return entry.site_instance(); 739 return dest_instance;
748 } 740 }
749 741
750 // If a swap is required, we need to force the SiteInstance AND 742 // If a swap is required, we need to force the SiteInstance AND
751 // BrowsingInstance to be different ones, using CreateForURL. 743 // BrowsingInstance to be different ones, using CreateForURL.
752 if (force_browsing_instance_swap) 744 if (force_browsing_instance_swap)
753 return SiteInstance::CreateForURL(browser_context, dest_url); 745 return SiteInstance::CreateForURL(browser_context, dest_url);
754 746
755 // (UGLY) HEURISTIC, process-per-site only: 747 // (UGLY) HEURISTIC, process-per-site only:
756 // 748 //
757 // If this navigation is generated, then it probably corresponds to a search 749 // If this navigation is generated, then it probably corresponds to a search
758 // query. Given that search results typically lead to users navigating to 750 // 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 751 // other sites, we don't really want to use the search engine hostname to
760 // determine the site instance for this navigation. 752 // determine the site instance for this navigation.
761 // 753 //
762 // NOTE: This can be removed once we have a way to transition between 754 // NOTE: This can be removed once we have a way to transition between
763 // RenderViews in response to a link click. 755 // RenderViews in response to a link click.
764 // 756 //
765 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && 757 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
766 PageTransitionCoreTypeIs(entry.GetTransitionType(), 758 PageTransitionCoreTypeIs(dest_transition, PAGE_TRANSITION_GENERATED)) {
767 PAGE_TRANSITION_GENERATED)) {
768 return current_instance; 759 return current_instance;
769 } 760 }
770 761
771 SiteInstanceImpl* current_site_instance = 762 SiteInstanceImpl* current_site_instance =
772 static_cast<SiteInstanceImpl*>(current_instance); 763 static_cast<SiteInstanceImpl*>(current_instance);
773 764
774 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it 765 // 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 766 // for this entry. We won't commit the SiteInstance to this site until the
776 // navigation commits (in DidNavigate), unless the navigation entry was 767 // navigation commits (in DidNavigate), unless the navigation entry was
777 // restored or it's a Web UI as described below. 768 // restored or it's a Web UI as described below.
(...skipping 21 matching lines...) Expand all
799 // not want to use the current_instance if it has no site, since it will 790 // 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 791 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for
801 // this URL instead (with the correct process type). 792 // this URL instead (with the correct process type).
802 if (current_site_instance->HasWrongProcessForURL(dest_url)) 793 if (current_site_instance->HasWrongProcessForURL(dest_url))
803 return current_site_instance->GetRelatedSiteInstance(dest_url); 794 return current_site_instance->GetRelatedSiteInstance(dest_url);
804 795
805 // View-source URLs must use a new SiteInstance and BrowsingInstance. 796 // View-source URLs must use a new SiteInstance and BrowsingInstance.
806 // TODO(nasko): This is the same condition as later in the function. This 797 // 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 798 // should be taken into account when refactoring this method as part of
808 // http://crbug.com/123007. 799 // http://crbug.com/123007.
809 if (entry.IsViewSourceMode()) 800 if (dest_is_view_source_mode)
810 return SiteInstance::CreateForURL(browser_context, dest_url); 801 return SiteInstance::CreateForURL(browser_context, dest_url);
811 802
812 // If we are navigating from a blank SiteInstance to a WebUI, make sure we 803 // If we are navigating from a blank SiteInstance to a WebUI, make sure we
813 // create a new SiteInstance. 804 // create a new SiteInstance.
814 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 805 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
815 browser_context, dest_url)) { 806 browser_context, dest_url)) {
816 return SiteInstance::CreateForURL(browser_context, dest_url); 807 return SiteInstance::CreateForURL(browser_context, dest_url);
817 } 808 }
818 809
819 // Normally the "site" on the SiteInstance is set lazily when the load 810 // Normally the "site" on the SiteInstance is set lazily when the load
820 // actually commits. This is to support better process sharing in case 811 // 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 812 // the site redirects to some other site: we want to use the destination
822 // site in the site instance. 813 // site in the site instance.
823 // 814 //
824 // In the case of session restore, as it loads all the pages immediately 815 // 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 816 // we need to set the site first, otherwise after a restore none of the
826 // pages would share renderers in process-per-site. 817 // pages would share renderers in process-per-site.
827 // 818 //
828 // The embedder can request some urls never to be assigned to SiteInstance 819 // The embedder can request some urls never to be assigned to SiteInstance
829 // through the ShouldAssignSiteForURL() content client method, so that 820 // through the ShouldAssignSiteForURL() content client method, so that
830 // renderers created for particular chrome urls (e.g. the chrome-native:// 821 // renderers created for particular chrome urls (e.g. the chrome-native://
831 // scheme) can be reused for subsequent navigations in the same WebContents. 822 // scheme) can be reused for subsequent navigations in the same WebContents.
832 // See http://crbug.com/386542. 823 // See http://crbug.com/386542.
833 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE && 824 if (dest_is_restore &&
834 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { 825 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) {
835 current_site_instance->SetSite(dest_url); 826 current_site_instance->SetSite(dest_url);
836 } 827 }
837 828
838 return current_site_instance; 829 return current_site_instance;
839 } 830 }
840 831
841 // Otherwise, only create a new SiteInstance for a cross-site navigation. 832 // Otherwise, only create a new SiteInstance for a cross-site navigation.
842 833
843 // TODO(creis): Once we intercept links and script-based navigations, we 834 // TODO(creis): Once we intercept links and script-based navigations, we
(...skipping 22 matching lines...) Expand all
866 // practice.) 857 // practice.)
867 const GURL& current_url = (current_entry) ? current_entry->GetURL() : 858 const GURL& current_url = (current_entry) ? current_entry->GetURL() :
868 current_instance->GetSiteURL(); 859 current_instance->GetSiteURL();
869 860
870 // View-source URLs must use a new SiteInstance and BrowsingInstance. 861 // 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 862 // We don't need a swap when going from view-source to a debug URL like
872 // chrome://crash, however. 863 // chrome://crash, however.
873 // TODO(creis): Refactor this method so this duplicated code isn't needed. 864 // TODO(creis): Refactor this method so this duplicated code isn't needed.
874 // See http://crbug.com/123007. 865 // See http://crbug.com/123007.
875 if (current_entry && 866 if (current_entry &&
876 current_entry->IsViewSourceMode() != entry.IsViewSourceMode() && 867 current_entry->IsViewSourceMode() != dest_is_view_source_mode &&
877 !IsRendererDebugURL(dest_url)) { 868 !IsRendererDebugURL(dest_url)) {
878 return SiteInstance::CreateForURL(browser_context, dest_url); 869 return SiteInstance::CreateForURL(browser_context, dest_url);
879 } 870 }
880 871
881 // Use the current SiteInstance for same site navigations, as long as the 872 // 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 873 // process type is correct. (The URL may have been installed as an app since
883 // the last time we visited it.) 874 // the last time we visited it.)
884 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 875 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
885 !current_site_instance->HasWrongProcessForURL(dest_url)) { 876 !current_site_instance->HasWrongProcessForURL(dest_url)) {
886 return current_instance; 877 return current_instance;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 // We do not currently swap processes for navigations in webview tag guests. 1316 // We do not currently swap processes for navigations in webview tag guests.
1326 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); 1317 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
1327 1318
1328 // Determine if we need a new BrowsingInstance for this entry. If true, this 1319 // 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 1320 // 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. 1321 // 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 1322 // This is used for cases that require a process swap even in the
1332 // process-per-tab model, such as WebUI pages. 1323 // process-per-tab model, such as WebUI pages.
1333 const NavigationEntry* current_entry = 1324 const NavigationEntry* current_entry =
1334 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1325 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1326 BrowserContext* browser_context =
1327 delegate_->GetControllerForRenderManager().GetBrowserContext();
1328 const GURL& current_effective_url = current_entry ?
1329 SiteInstanceImpl::GetEffectiveURL(browser_context,
1330 current_entry->GetURL()) :
1331 render_frame_host_->GetSiteInstance()->GetSiteURL();
1332 bool current_is_view_source_mode = current_entry ?
1333 current_entry->IsViewSourceMode() : entry.IsViewSourceMode();
1335 bool force_swap = !is_guest_scheme && 1334 bool force_swap = !is_guest_scheme &&
1336 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry); 1335 ShouldSwapBrowsingInstancesForNavigation(
1337 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) 1336 current_effective_url,
1338 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap); 1337 current_is_view_source_mode,
1338 entry.site_instance(),
1339 SiteInstanceImpl::GetEffectiveURL(browser_context, entry.GetURL()),
1340 entry.IsViewSourceMode());
1341 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) {
1342 new_instance = GetSiteInstanceForURL(
1343 entry.GetURL(),
1344 entry.site_instance(),
1345 entry.GetTransitionType(),
1346 entry.restore_type() != NavigationEntryImpl::RESTORE_NONE,
1347 entry.IsViewSourceMode(),
1348 current_instance,
1349 force_swap);
1350 }
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698