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

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

Issue 967383002: PlzNavigate: Avoid duplicate SiteInstance creation during navigation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Extract RFH selection logic form GetFrameHostForNavigation. Created 5 years, 9 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/logging.h" 10 #include "base/logging.h"
(...skipping 23 matching lines...) Expand all
34 #include "content/public/browser/notification_service.h" 34 #include "content/public/browser/notification_service.h"
35 #include "content/public/browser/notification_types.h" 35 #include "content/public/browser/notification_types.h"
36 #include "content/public/browser/render_widget_host_iterator.h" 36 #include "content/public/browser/render_widget_host_iterator.h"
37 #include "content/public/browser/render_widget_host_view.h" 37 #include "content/public/browser/render_widget_host_view.h"
38 #include "content/public/browser/user_metrics.h" 38 #include "content/public/browser/user_metrics.h"
39 #include "content/public/browser/web_ui_controller.h" 39 #include "content/public/browser/web_ui_controller.h"
40 #include "content/public/common/content_switches.h" 40 #include "content/public/common/content_switches.h"
41 #include "content/public/common/referrer.h" 41 #include "content/public/common/referrer.h"
42 #include "content/public/common/url_constants.h" 42 #include "content/public/common/url_constants.h"
43 43
44 namespace {
45
46 // Stores information regarding a SiteInstance targeted at a specific URL. It
47 // can whether point to an existent one or store the details needed to create a
48 // new one.
49 struct SiteInstanceDescriptor {
50 explicit SiteInstanceDescriptor(content::SiteInstance* site_instance)
51 : existent_site_instance(site_instance),
52 new_site_is_related_to_current(false) {}
53
54 SiteInstanceDescriptor(GURL site_url, bool related_to_current)
55 : existent_site_instance(nullptr),
56 new_site_url(site_url),
57 new_site_is_related_to_current(related_to_current) {}
58
59 // Set with an existent SiteInstance to be reused.
60 content::SiteInstance* existent_site_instance;
61 // In case |existent_site_instance| is null, specify a new site URL.
62 GURL new_site_url;
63 // In case |existent_site_instance| is null, specify if the new site should be
64 // created in new BrowsingInstance or not.
65 bool new_site_is_related_to_current;
66 };
67
68 } // namespace
69
44 namespace content { 70 namespace content {
45 71
46 // static 72 // static
47 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) { 73 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) {
48 node->render_manager()->pending_delete_hosts_.clear(); 74 node->render_manager()->pending_delete_hosts_.clear();
49 return true; 75 return true;
50 } 76 }
51 77
52 RenderFrameHostManager::RenderFrameHostManager( 78 RenderFrameHostManager::RenderFrameHostManager(
53 FrameTreeNode* frame_tree_node, 79 FrameTreeNode* frame_tree_node,
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 RenderFrameHostImpl* dest_rfh = GetFrameHostForNavigation(request); 760 RenderFrameHostImpl* dest_rfh = GetFrameHostForNavigation(request);
735 DCHECK(dest_rfh); 761 DCHECK(dest_rfh);
736 } 762 }
737 763
738 // PlzNavigate 764 // PlzNavigate
739 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 765 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
740 const NavigationRequest& request) { 766 const NavigationRequest& request) {
741 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 767 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
742 switches::kEnableBrowserSideNavigation)); 768 switches::kEnableBrowserSideNavigation));
743 769
744 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); 770 // To be set with the (currently) appropriate RenderFrameHost to commit this
745 771 // navigation.
746 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
747 request.common_params().url, request.source_site_instance(),
748 request.dest_site_instance(), request.common_params().transition,
749 request.restore_type() != NavigationEntryImpl::RESTORE_NONE,
750 request.is_view_source());
751 // The appropriate RenderFrameHost to commit the navigation.
752 RenderFrameHostImpl* navigation_rfh = nullptr; 772 RenderFrameHostImpl* navigation_rfh = nullptr;
753 773
754 // Renderer-initiated navigations that may require a SiteInstance swap are 774 RenderFrameHostToUse rfh_to_use = INVALID;
755 // sent to the browser via the OpenURL IPC and are afterwards treated as 775 scoped_refptr<SiteInstance> dest_site_instance =
756 // browser-initiated navigations. NavigationRequests marked as 776 ChooseFrameHostForNavigation(request, &rfh_to_use);
757 // renderer-initiated are created by receiving a BeginNavigation IPC, and will
758 // then proceed in the same renderer that sent the IPC due to the condition
759 // below.
760 // TODO(carlosk): Once there is support for cross-process scripting check for
761 // non-browser-initiated navigations should be removed (see crbug.com/440266).
762 if (current_site_instance == dest_site_instance.get() ||
763 !request.browser_initiated() ||
764 (!frame_tree_node_->IsMainFrame() &&
765 !base::CommandLine::ForCurrentProcess()->HasSwitch(
766 switches::kSitePerProcess))) {
767 // Reuse the current RFH if its SiteInstance matches the the navigation's
768 // or if this is a subframe navigation. We only swap RFHs for subframes when
769 // --site-per-process is enabled.
770 CleanUpNavigation();
771 navigation_rfh = render_frame_host_.get();
772 777
773 // As SiteInstances are the same, check if the WebUI should be reused. 778 switch (rfh_to_use) {
774 const NavigationEntry* current_navigation_entry = 779 case REUSE_CURRENT: {
775 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 780 CleanUpNavigation();
776 bool should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, 781 navigation_rfh = render_frame_host_.get();
777 request.common_params().url); 782
carlosk 2015/03/23 14:31:18 I fixed this bug (this is the 2nd time I think) of
778 if (!should_reuse_web_ui_) { 783 // As SiteInstances are the same, check if the WebUI should be reused.
779 speculative_web_ui_ = CreateWebUI(request.common_params().url, 784 const NavigationEntry* current_navigation_entry =
780 request.bindings()); 785 delegate_->GetLastCommittedNavigationEntryForRenderManager();
781 // Make sure the current RenderViewHost has the right bindings. 786 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry,
782 if (speculative_web_ui() && 787 request.common_params().url);
783 !render_frame_host_->GetProcess()->IsIsolatedGuest()) { 788 if (!should_reuse_web_ui_) {
784 render_frame_host_->render_view_host()->AllowBindings( 789 speculative_web_ui_ =
785 speculative_web_ui()->GetBindings()); 790 CreateWebUI(request.common_params().url, request.bindings());
791 // Make sure the current RenderViewHost has the right bindings.
792 if (speculative_web_ui() &&
793 !render_frame_host_->GetProcess()->IsIsolatedGuest()) {
794 render_frame_host_->render_view_host()->AllowBindings(
795 speculative_web_ui()->GetBindings());
796 }
786 } 797 }
798 break;
787 } 799 }
788 } else { 800 case NEW_SPECULATIVE: {
789 // If the SiteInstance for the final URL doesn't match the one from the 801 DCHECK(dest_site_instance);
790 // speculatively created RenderFrameHost, create a new RenderFrameHost using
791 // this new SiteInstance.
792 if (!speculative_render_frame_host_ ||
793 speculative_render_frame_host_->GetSiteInstance() !=
794 dest_site_instance.get()) {
795 CleanUpNavigation(); 802 CleanUpNavigation();
796 bool success = CreateSpeculativeRenderFrameHost( 803 bool success = CreateSpeculativeRenderFrameHost(
797 request.common_params().url, current_site_instance, 804 request.common_params().url, render_frame_host_->GetSiteInstance(),
798 dest_site_instance.get(), request.bindings()); 805 dest_site_instance.get(), request.bindings());
799 DCHECK(success); 806 DCHECK(success);
807 // fall through
800 } 808 }
801 DCHECK(speculative_render_frame_host_); 809 case REUSE_SPECULATIVE: {
802 navigation_rfh = speculative_render_frame_host_.get(); 810 DCHECK(speculative_render_frame_host_);
811 navigation_rfh = speculative_render_frame_host_.get();
803 812
804 // Check if our current RFH is live. 813 // Check if our current RFH is live.
805 if (!render_frame_host_->IsRenderFrameLive()) { 814 if (!render_frame_host_->IsRenderFrameLive()) {
806 // The current RFH is not live. There's no reason to sit around with a 815 // The current RFH is not live. There's no reason to sit around with a
807 // sad tab or a newly created RFH while we wait for the navigation to 816 // sad tab or a newly created RFH while we wait for the navigation to
808 // complete. Just switch to the speculative RFH now and go back to non 817 // complete. Just switch to the speculative RFH now and go back to non
809 // cross-navigating (Note that we don't care about on{before}unload 818 // cross-navigating (Note that we don't care about on{before}unload
810 // handlers if the current RFH isn't live.) 819 // handlers if the current RFH isn't live.)
811 CommitPending(); 820 CommitPending();
carlosk 2015/03/23 14:31:18 This early commit when the current frame is not li
821 }
822 break;
812 } 823 }
824 default: { NOTREACHED(); }
carlosk 2015/03/23 14:31:18 I already added the adequate line breaks on my mac
carlosk 2015/03/23 17:43:01 Surprisingly, this is the formating that git cl fo
813 } 825 }
826
814 DCHECK(navigation_rfh && 827 DCHECK(navigation_rfh &&
815 (navigation_rfh == render_frame_host_.get() || 828 (navigation_rfh == render_frame_host_.get() ||
816 navigation_rfh == speculative_render_frame_host_.get())); 829 navigation_rfh == speculative_render_frame_host_.get()));
817 830
818 // If the RenderFrame that needs to navigate is not live (its process was just 831 // If the RenderFrame that needs to navigate is not live (its process was just
819 // created or has crashed), initialize it. 832 // created or has crashed), initialize it.
820 if (!navigation_rfh->IsRenderFrameLive()) { 833 if (!navigation_rfh->IsRenderFrameLive()) {
821 // Recreate the opener chain. 834 // Recreate the opener chain.
822 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 835 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
823 navigation_rfh->GetSiteInstance()); 836 navigation_rfh->GetSiteInstance());
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 const GURL& new_url) const { 1027 const GURL& new_url) const {
1015 NavigationControllerImpl& controller = 1028 NavigationControllerImpl& controller =
1016 delegate_->GetControllerForRenderManager(); 1029 delegate_->GetControllerForRenderManager();
1017 return current_entry && web_ui_.get() && 1030 return current_entry && web_ui_.get() &&
1018 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 1031 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1019 controller.GetBrowserContext(), current_entry->GetURL()) == 1032 controller.GetBrowserContext(), current_entry->GetURL()) ==
1020 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 1033 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1021 controller.GetBrowserContext(), new_url)); 1034 controller.GetBrowserContext(), new_url));
1022 } 1035 }
1023 1036
1037 // PlzNavigate
1038 scoped_refptr<SiteInstance>
1039 RenderFrameHostManager::ChooseFrameHostForNavigation(
1040 const NavigationRequest& request,
1041 RenderFrameHostToUse* rfh_to_use) {
1042 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1043 switches::kEnableBrowserSideNavigation));
1044
1045 if (speculative_render_frame_host_ &&
1046 IsCorrectSiteInstanceForURL(
1047 speculative_render_frame_host_->GetSiteInstance(),
1048 request.common_params().url, request.source_site_instance(),
1049 request.dest_site_instance(), request.common_params().transition,
1050 request.restore_type() != NavigationEntryImpl::RESTORE_NONE,
1051 request.is_view_source())) {
1052 *rfh_to_use = REUSE_SPECULATIVE;
1053 return nullptr;
1054 }
1055
1056 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
1057 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
1058 request.common_params().url, request.source_site_instance(),
1059 request.dest_site_instance(), request.common_params().transition,
1060 request.restore_type() != NavigationEntryImpl::RESTORE_NONE,
1061 request.is_view_source());
1062
1063 // Renderer-initiated navigations that may require a SiteInstance swap are
1064 // sent to the browser via the OpenURL IPC and are afterwards treated as
1065 // browser-initiated navigations. NavigationRequests marked as
1066 // renderer-initiated are created by receiving a BeginNavigation IPC, and will
1067 // then proceed in the same renderer that sent the IPC due to the condition
1068 // below.
1069 // TODO(carlosk): Once there is support for cross-process scripting check for
1070 // non-browser-initiated navigations should be removed (see crbug.com/440266).
1071 if (current_site_instance == dest_site_instance.get() ||
1072 !request.browser_initiated() ||
1073 (!frame_tree_node_->IsMainFrame() &&
1074 !base::CommandLine::ForCurrentProcess()->HasSwitch(
1075 switches::kSitePerProcess))) {
1076 // Reuse the current RFH if its SiteInstance matches the the navigation's,
1077 // if it's renderer initiated or if this is a subframe navigation. We only
1078 // swap RFHs for subframes when --site-per-process is enabled.
1079 *rfh_to_use = REUSE_CURRENT;
1080 return nullptr;
1081 }
1082
1083 // If the SiteInstance for the final URL doesn't match the one from the
1084 // speculatively created RenderFrameHost, create a new RenderFrameHost using
1085 // this new SiteInstance.
1086 if (!speculative_render_frame_host_ ||
1087 speculative_render_frame_host_->GetSiteInstance() !=
1088 dest_site_instance.get()) {
1089 *rfh_to_use = NEW_SPECULATIVE;
1090 return dest_site_instance;
1091 }
1092
1093 *rfh_to_use = REUSE_SPECULATIVE;
1094 return nullptr;
1095 }
1096
1024 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( 1097 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
1025 const GURL& dest_url, 1098 const GURL& dest_url,
1026 SiteInstance* source_instance, 1099 SiteInstance* source_instance,
1027 SiteInstance* dest_instance, 1100 SiteInstance* dest_instance,
1028 ui::PageTransition transition, 1101 ui::PageTransition transition,
1029 bool dest_is_restore, 1102 bool dest_is_restore,
1030 bool dest_is_view_source_mode) { 1103 bool dest_is_view_source_mode) {
1104 SiteInstanceDescriptor descriptor = DetermineSiteInstanceForURL(
1105 dest_url, source_instance, dest_instance, transition, dest_is_restore,
1106 dest_is_view_source_mode);
1107
1108 if (descriptor.existent_site_instance)
1109 return descriptor.existent_site_instance;
1110
1111 if (descriptor.new_site_is_related_to_current) {
1112 return render_frame_host_->GetSiteInstance()->GetRelatedSiteInstance(
1113 descriptor.new_site_url);
1114 }
1115
1116 return SiteInstance::CreateForURL(
1117 delegate_->GetControllerForRenderManager().GetBrowserContext(),
1118 descriptor.new_site_url);
1119 }
1120
1121 // PlzNavigate
1122 bool RenderFrameHostManager::IsCorrectSiteInstanceForURL(
1123 SiteInstance* candidate_instance,
1124 const GURL& dest_url,
1125 SiteInstance* source_instance,
1126 SiteInstance* dest_instance,
1127 ui::PageTransition transition,
1128 bool dest_is_restore,
1129 bool dest_is_view_source_mode) {
1130 CHECK(candidate_instance);
1131
1132 SiteInstanceDescriptor descriptor = DetermineSiteInstanceForURL(
1133 dest_url, source_instance, dest_instance, transition, dest_is_restore,
1134 dest_is_view_source_mode);
1135
1136 if (descriptor.existent_site_instance)
1137 return descriptor.existent_site_instance == candidate_instance;
carlosk 2015/03/23 14:31:18 Confirming: there should be no two SiteInstances u
1138
1139 BrowserContext* browser_context =
1140 delegate_->GetControllerForRenderManager().GetBrowserContext();
1141 bool candidate_is_related =
1142 render_frame_host_->GetSiteInstance()->IsRelatedSiteInstance(
1143 candidate_instance);
1144
1145 // Note: this handles both the cases when a) the new site should be related
1146 // and the candidate is and b) the new site should not be related and the
1147 // candidate is not. Hence the boolean equality check.
1148 if (descriptor.new_site_is_related_to_current == candidate_is_related) {
1149 return (candidate_instance->GetSiteURL() ==
1150 SiteInstanceImpl::GetSiteForURL(browser_context,
1151 descriptor.new_site_url));
1152 }
1153
1154 return false;
1155 }
1156
1157 SiteInstanceDescriptor RenderFrameHostManager::DetermineSiteInstanceForURL(
carlosk 2015/03/23 14:31:18 I am returning SiteInstanceDescriptor by value her
clamy 2015/03/23 15:26:44 Seems reasonable.
1158 const GURL& dest_url,
1159 SiteInstance* source_instance,
1160 SiteInstance* dest_instance,
1161 ui::PageTransition transition,
1162 bool dest_is_restore,
1163 bool dest_is_view_source_mode) {
1031 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1164 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1032 SiteInstance* new_instance = current_instance; 1165 SiteInstanceDescriptor descriptor = SiteInstanceDescriptor(current_instance);
1166 bool force_browsing_instance_swap = false;
1033 1167
1034 // We do not currently swap processes for navigations in webview tag guests. 1168 // We do not currently swap processes for navigations in webview tag guests.
1035 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) 1169 if (!current_instance->GetSiteURL().SchemeIs(kGuestScheme)) {
1036 return current_instance; 1170 // Determine if we need a new BrowsingInstance for this entry. If true, this
1037 1171 // implies that it will get a new SiteInstance (and likely process), and
1038 // Determine if we need a new BrowsingInstance for this entry. If true, this 1172 // that other tabs in the current BrowsingInstance will be unable to script
1039 // implies that it will get a new SiteInstance (and likely process), and that 1173 // it. This is used for cases that require a process swap even in the
1040 // other tabs in the current BrowsingInstance will be unable to script it. 1174 // process-per-tab model, such as WebUI pages.
1041 // This is used for cases that require a process swap even in the 1175 // TODO(clamy): Remove the dependency on the current entry.
1042 // process-per-tab model, such as WebUI pages. 1176 NavigationEntry* current_entry =
1043 // TODO(clamy): Remove the dependency on the current entry. 1177 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1044 const NavigationEntry* current_entry = 1178 BrowserContext* browser_context =
1045 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1179 delegate_->GetControllerForRenderManager().GetBrowserContext();
1046 BrowserContext* browser_context = 1180 const GURL& current_effective_url =
1047 delegate_->GetControllerForRenderManager().GetBrowserContext(); 1181 current_entry ? SiteInstanceImpl::GetEffectiveURL(
1048 const GURL& current_effective_url = current_entry ? 1182 browser_context, current_entry->GetURL())
1049 SiteInstanceImpl::GetEffectiveURL(browser_context, 1183 : render_frame_host_->GetSiteInstance()->GetSiteURL();
1050 current_entry->GetURL()) : 1184 bool current_is_view_source_mode = current_entry
1051 render_frame_host_->GetSiteInstance()->GetSiteURL(); 1185 ? current_entry->IsViewSourceMode()
1052 bool current_is_view_source_mode = current_entry ? 1186 : dest_is_view_source_mode;
1053 current_entry->IsViewSourceMode() : dest_is_view_source_mode; 1187 force_browsing_instance_swap = ShouldSwapBrowsingInstancesForNavigation(
1054 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( 1188 current_effective_url, current_is_view_source_mode, dest_instance,
1055 current_effective_url, 1189 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
1056 current_is_view_source_mode, 1190 dest_is_view_source_mode);
1057 dest_instance, 1191 if (ShouldTransitionCrossSite() || force_browsing_instance_swap) {
1058 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), 1192 descriptor = DetermineSiteInstanceForURLInternal(
1059 dest_is_view_source_mode); 1193 dest_url, source_instance, current_instance, dest_instance,
1060 if (ShouldTransitionCrossSite() || force_swap) { 1194 transition, dest_is_restore, dest_is_view_source_mode,
1061 new_instance = GetSiteInstanceForURL( 1195 force_browsing_instance_swap);
1062 dest_url, source_instance, current_instance, dest_instance, 1196 }
1063 transition, dest_is_restore, dest_is_view_source_mode, force_swap);
1064 } 1197 }
1065 1198
1066 // If force_swap is true, we must use a different SiteInstance. If we didn't, 1199 // If |force_browsing_instance_swap| is true, we must use a different
1067 // we would have two RenderFrameHosts in the same SiteInstance and the same 1200 // SiteInstance than the current one. If we didn't, we would have two
1068 // frame, resulting in page_id conflicts for their NavigationEntries. 1201 // RenderFrameHosts in the same SiteInstance and the same frame, resulting in
1069 if (force_swap) 1202 // page_id conflicts for their NavigationEntries.
1070 CHECK_NE(new_instance, current_instance); 1203 if (force_browsing_instance_swap && descriptor.existent_site_instance)
1071 return new_instance; 1204 CHECK_NE(current_instance, descriptor.existent_site_instance);
1205
1206 return descriptor;
1072 } 1207 }
1073 1208
1074 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( 1209 SiteInstanceDescriptor
1210 RenderFrameHostManager::DetermineSiteInstanceForURLInternal(
1075 const GURL& dest_url, 1211 const GURL& dest_url,
1076 SiteInstance* source_instance, 1212 SiteInstance* source_instance,
1077 SiteInstance* current_instance, 1213 SiteInstance* current_instance,
1078 SiteInstance* dest_instance, 1214 SiteInstance* dest_instance,
1079 ui::PageTransition transition, 1215 ui::PageTransition transition,
1080 bool dest_is_restore, 1216 bool dest_is_restore,
1081 bool dest_is_view_source_mode, 1217 bool dest_is_view_source_mode,
1082 bool force_browsing_instance_swap) { 1218 bool force_browsing_instance_swap) {
1219 SiteInstanceImpl* current_instance_impl =
1220 static_cast<SiteInstanceImpl*>(current_instance);
1083 NavigationControllerImpl& controller = 1221 NavigationControllerImpl& controller =
1084 delegate_->GetControllerForRenderManager(); 1222 delegate_->GetControllerForRenderManager();
1085 BrowserContext* browser_context = controller.GetBrowserContext(); 1223 BrowserContext* browser_context = controller.GetBrowserContext();
1086 1224
1087 // If the entry has an instance already we should use it. 1225 // If the entry has an instance already we should use it.
1088 if (dest_instance) { 1226 if (dest_instance) {
1089 // If we are forcing a swap, this should be in a different BrowsingInstance. 1227 // If we are forcing a swap, this should be in a different BrowsingInstance.
1090 if (force_browsing_instance_swap) { 1228 if (force_browsing_instance_swap) {
1091 CHECK(!dest_instance->IsRelatedSiteInstance( 1229 CHECK(!dest_instance->IsRelatedSiteInstance(
1092 render_frame_host_->GetSiteInstance())); 1230 render_frame_host_->GetSiteInstance()));
1093 } 1231 }
1094 return dest_instance; 1232 return SiteInstanceDescriptor(dest_instance);
1095 } 1233 }
1096 1234
1097 // If a swap is required, we need to force the SiteInstance AND 1235 // If a swap is required, we need to force the SiteInstance AND
1098 // BrowsingInstance to be different ones, using CreateForURL. 1236 // BrowsingInstance to be different ones, using CreateForURL.
1099 if (force_browsing_instance_swap) 1237 if (force_browsing_instance_swap)
1100 return SiteInstance::CreateForURL(browser_context, dest_url); 1238 return SiteInstanceDescriptor(dest_url, false);
1101 1239
1102 // (UGLY) HEURISTIC, process-per-site only: 1240 // (UGLY) HEURISTIC, process-per-site only:
1103 // 1241 //
1104 // If this navigation is generated, then it probably corresponds to a search 1242 // If this navigation is generated, then it probably corresponds to a search
1105 // query. Given that search results typically lead to users navigating to 1243 // query. Given that search results typically lead to users navigating to
1106 // other sites, we don't really want to use the search engine hostname to 1244 // other sites, we don't really want to use the search engine hostname to
1107 // determine the site instance for this navigation. 1245 // determine the site instance for this navigation.
1108 // 1246 //
1109 // NOTE: This can be removed once we have a way to transition between 1247 // NOTE: This can be removed once we have a way to transition between
1110 // RenderViews in response to a link click. 1248 // RenderViews in response to a link click.
1111 // 1249 //
1112 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 1250 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1113 switches::kProcessPerSite) && 1251 switches::kProcessPerSite) &&
1114 ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED)) { 1252 ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED)) {
1115 return current_instance; 1253 return SiteInstanceDescriptor(current_instance_impl);
1116 } 1254 }
1117 1255
1118 SiteInstanceImpl* current_site_instance =
1119 static_cast<SiteInstanceImpl*>(current_instance);
1120
1121 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it 1256 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
1122 // for this entry. We won't commit the SiteInstance to this site until the 1257 // for this entry. We won't commit the SiteInstance to this site until the
1123 // navigation commits (in DidNavigate), unless the navigation entry was 1258 // navigation commits (in DidNavigate), unless the navigation entry was
1124 // restored or it's a Web UI as described below. 1259 // restored or it's a Web UI as described below.
1125 if (!current_site_instance->HasSite()) { 1260 if (!current_instance_impl->HasSite()) {
1126 // If we've already created a SiteInstance for our destination, we don't 1261 // If we've already created a SiteInstance for our destination, we don't
1127 // want to use this unused SiteInstance; use the existing one. (We don't 1262 // want to use this unused SiteInstance; use the existing one. (We don't
1128 // do this check if the current_instance has a site, because for now, we 1263 // do this check if the current_instance_impl has a site, because for now,
1129 // want to compare against the current URL and not the SiteInstance's site. 1264 // we want to compare against the current URL and not the SiteInstance's
1130 // In this case, there is no current URL, so comparing against the site is 1265 // site. In this case, there is no current URL, so comparing against the
1131 // ok. See additional comments below.) 1266 // site is ok. See additional comments below.)
1132 // 1267 //
1133 // Also, if the URL should use process-per-site mode and there is an 1268 // Also, if the URL should use process-per-site mode and there is an
1134 // existing process for the site, we should use it. We can call 1269 // existing process for the site, we should use it. We can call
1135 // GetRelatedSiteInstance() for this, which will eagerly set the site and 1270 // GetRelatedSiteInstance() for this, which will eagerly set the site and
1136 // thus use the correct process. 1271 // thus use the correct process.
1137 bool use_process_per_site = 1272 bool use_process_per_site =
1138 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && 1273 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
1139 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); 1274 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url);
1140 if (current_site_instance->HasRelatedSiteInstance(dest_url) || 1275 if (current_instance_impl->HasRelatedSiteInstance(dest_url) ||
1141 use_process_per_site) { 1276 use_process_per_site) {
1142 return current_site_instance->GetRelatedSiteInstance(dest_url); 1277 return SiteInstanceDescriptor(dest_url, true);
1143 } 1278 }
1144 1279
1145 // For extensions, Web UI URLs (such as the new tab page), and apps we do 1280 // For extensions, Web UI URLs (such as the new tab page), and apps we do
1146 // not want to use the current_instance if it has no site, since it will 1281 // not want to use the current_instance_impl if it has no site, since it
1147 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for 1282 // will have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance
1148 // this URL instead (with the correct process type). 1283 // for this URL instead (with the correct process type).
1149 if (current_site_instance->HasWrongProcessForURL(dest_url)) 1284 if (current_instance_impl->HasWrongProcessForURL(dest_url))
1150 return current_site_instance->GetRelatedSiteInstance(dest_url); 1285 return SiteInstanceDescriptor(dest_url, true);
1151 1286
1152 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1287 // View-source URLs must use a new SiteInstance and BrowsingInstance.
1153 // TODO(nasko): This is the same condition as later in the function. This 1288 // TODO(nasko): This is the same condition as later in the function. This
1154 // should be taken into account when refactoring this method as part of 1289 // should be taken into account when refactoring this method as part of
1155 // http://crbug.com/123007. 1290 // http://crbug.com/123007.
1156 if (dest_is_view_source_mode) 1291 if (dest_is_view_source_mode)
1157 return SiteInstance::CreateForURL(browser_context, dest_url); 1292 return SiteInstanceDescriptor(dest_url, false);
1158 1293
1159 // If we are navigating from a blank SiteInstance to a WebUI, make sure we 1294 // If we are navigating from a blank SiteInstance to a WebUI, make sure we
1160 // create a new SiteInstance. 1295 // create a new SiteInstance.
1161 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 1296 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
1162 browser_context, dest_url)) { 1297 browser_context, dest_url)) {
1163 return SiteInstance::CreateForURL(browser_context, dest_url); 1298 return SiteInstanceDescriptor(dest_url, false);
1164 } 1299 }
1165 1300
1166 // Normally the "site" on the SiteInstance is set lazily when the load 1301 // Normally the "site" on the SiteInstance is set lazily when the load
1167 // actually commits. This is to support better process sharing in case 1302 // actually commits. This is to support better process sharing in case
1168 // the site redirects to some other site: we want to use the destination 1303 // the site redirects to some other site: we want to use the destination
1169 // site in the site instance. 1304 // site in the site instance.
1170 // 1305 //
1171 // In the case of session restore, as it loads all the pages immediately 1306 // In the case of session restore, as it loads all the pages immediately
1172 // we need to set the site first, otherwise after a restore none of the 1307 // we need to set the site first, otherwise after a restore none of the
1173 // pages would share renderers in process-per-site. 1308 // pages would share renderers in process-per-site.
1174 // 1309 //
1175 // The embedder can request some urls never to be assigned to SiteInstance 1310 // The embedder can request some urls never to be assigned to SiteInstance
1176 // through the ShouldAssignSiteForURL() content client method, so that 1311 // through the ShouldAssignSiteForURL() content client method, so that
1177 // renderers created for particular chrome urls (e.g. the chrome-native:// 1312 // renderers created for particular chrome urls (e.g. the chrome-native://
1178 // scheme) can be reused for subsequent navigations in the same WebContents. 1313 // scheme) can be reused for subsequent navigations in the same WebContents.
1179 // See http://crbug.com/386542. 1314 // See http://crbug.com/386542.
1180 if (dest_is_restore && 1315 if (dest_is_restore &&
1181 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { 1316 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) {
1182 current_site_instance->SetSite(dest_url); 1317 current_instance_impl->SetSite(dest_url);
1183 } 1318 }
1184 1319
1185 return current_site_instance; 1320 return SiteInstanceDescriptor(current_instance_impl);
1186 } 1321 }
1187 1322
1188 // Otherwise, only create a new SiteInstance for a cross-site navigation. 1323 // Otherwise, only create a new SiteInstance for a cross-site navigation.
1189 1324
1190 // TODO(creis): Once we intercept links and script-based navigations, we 1325 // TODO(creis): Once we intercept links and script-based navigations, we
1191 // will be able to enforce that all entries in a SiteInstance actually have 1326 // will be able to enforce that all entries in a SiteInstance actually have
1192 // the same site, and it will be safe to compare the URL against the 1327 // the same site, and it will be safe to compare the URL against the
1193 // SiteInstance's site, as follows: 1328 // SiteInstance's site, as follows:
1194 // const GURL& current_url = current_instance->site(); 1329 // const GURL& current_url = current_instance_impl->site();
1195 // For now, though, we're in a hybrid model where you only switch 1330 // For now, though, we're in a hybrid model where you only switch
1196 // SiteInstances if you type in a cross-site URL. This means we have to 1331 // SiteInstances if you type in a cross-site URL. This means we have to
1197 // compare the entry's URL to the last committed entry's URL. 1332 // compare the entry's URL to the last committed entry's URL.
1198 NavigationEntry* current_entry = controller.GetLastCommittedEntry(); 1333 NavigationEntry* current_entry = controller.GetLastCommittedEntry();
1199 if (interstitial_page_) { 1334 if (interstitial_page_) {
1200 // The interstitial is currently the last committed entry, but we want to 1335 // The interstitial is currently the last committed entry, but we want to
1201 // compare against the last non-interstitial entry. 1336 // compare against the last non-interstitial entry.
1202 current_entry = controller.GetEntryAtOffset(-1); 1337 current_entry = controller.GetEntryAtOffset(-1);
1203 } 1338 }
carlosk 2015/03/23 14:31:18 There's this |current_entry| change here in case t
1204 1339
1205 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1340 // View-source URLs must use a new SiteInstance and BrowsingInstance.
1206 // We don't need a swap when going from view-source to a debug URL like 1341 // We don't need a swap when going from view-source to a debug URL like
1207 // chrome://crash, however. 1342 // chrome://crash, however.
1208 // TODO(creis): Refactor this method so this duplicated code isn't needed. 1343 // TODO(creis): Refactor this method so this duplicated code isn't needed.
1209 // See http://crbug.com/123007. 1344 // See http://crbug.com/123007.
1210 if (current_entry && 1345 if (current_entry &&
1211 current_entry->IsViewSourceMode() != dest_is_view_source_mode && 1346 current_entry->IsViewSourceMode() != dest_is_view_source_mode &&
1212 !IsRendererDebugURL(dest_url)) { 1347 !IsRendererDebugURL(dest_url)) {
1213 return SiteInstance::CreateForURL(browser_context, dest_url); 1348 return SiteInstanceDescriptor(dest_url, false);
1214 } 1349 }
1215 1350
1216 // Use the source SiteInstance in case of data URLs or about:blank pages, 1351 // Use the source SiteInstance in case of data URLs or about:blank pages,
1217 // because the content is then controlled and/or scriptable by the source 1352 // because the content is then controlled and/or scriptable by the source
1218 // SiteInstance. 1353 // SiteInstance.
1219 GURL about_blank(url::kAboutBlankURL); 1354 GURL about_blank(url::kAboutBlankURL);
1220 if (source_instance && 1355 if (source_instance &&
1221 (dest_url == about_blank || dest_url.scheme() == url::kDataScheme)) 1356 (dest_url == about_blank || dest_url.scheme() == url::kDataScheme)) {
1222 return source_instance; 1357 return SiteInstanceDescriptor(source_instance);
1358 }
1223 1359
1224 // Use the current SiteInstance for same site navigations, as long as the 1360 // Use the current SiteInstance for same site navigations, as long as the
1225 // process type is correct. (The URL may have been installed as an app since 1361 // process type is correct. (The URL may have been installed as an app since
1226 // the last time we visited it.) 1362 // the last time we visited it.)
1227 const GURL& current_url = 1363 const GURL& current_url =
1228 GetCurrentURLForSiteInstance(current_instance, current_entry); 1364 GetCurrentURLForSiteInstance(current_instance_impl, current_entry);
1229 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 1365 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
1230 !current_site_instance->HasWrongProcessForURL(dest_url)) { 1366 !current_instance_impl->HasWrongProcessForURL(dest_url)) {
1231 return current_instance; 1367 return SiteInstanceDescriptor(current_instance_impl);
1232 } 1368 }
1233 1369
1234 // Start the new renderer in a new SiteInstance, but in the current 1370 // Start the new renderer in a new SiteInstance, but in the current
1235 // BrowsingInstance. It is important to immediately give this new 1371 // BrowsingInstance. It is important to immediately give this new
1236 // SiteInstance to a RenderViewHost (if it is different than our current 1372 // SiteInstance to a RenderViewHost (if it is different than our current
1237 // SiteInstance), so that it is ref counted. This will happen in 1373 // SiteInstance), so that it is ref counted. This will happen in
1238 // CreateRenderView. 1374 // CreateRenderView.
1239 return current_instance->GetRelatedSiteInstance(dest_url); 1375 return SiteInstanceDescriptor(dest_url, true);
1240 } 1376 }
1241 1377
1242 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( 1378 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance(
1243 SiteInstance* current_instance, NavigationEntry* current_entry) { 1379 SiteInstance* current_instance, NavigationEntry* current_entry) {
1244 // If this is a subframe that is potentially out of process from its parent, 1380 // If this is a subframe that is potentially out of process from its parent,
1245 // don't consider using current_entry's url for SiteInstance selection, since 1381 // don't consider using current_entry's url for SiteInstance selection, since
1246 // current_entry's url is for the main frame and may be in a different site 1382 // current_entry's url is for the main frame and may be in a different site
1247 // than this frame. 1383 // than this frame.
1248 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. 1384 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url.
1249 // See http://crbug.com/369654 1385 // See http://crbug.com/369654
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 2155 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
2020 SiteInstance* instance) { 2156 SiteInstance* instance) {
2021 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 2157 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
2022 if (iter != proxy_hosts_.end()) { 2158 if (iter != proxy_hosts_.end()) {
2023 delete iter->second; 2159 delete iter->second;
2024 proxy_hosts_.erase(iter); 2160 proxy_hosts_.erase(iter);
2025 } 2161 }
2026 } 2162 }
2027 2163
2028 } // namespace content 2164 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698