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/logging.h" | 10 #include "base/logging.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |