OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_host_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "content/browser/child_process_security_policy_impl.h" | 13 #include "content/browser/child_process_security_policy_impl.h" |
14 #include "content/browser/devtools/render_view_devtools_agent_host.h" | 14 #include "content/browser/devtools/render_view_devtools_agent_host.h" |
15 #include "content/browser/frame_host/cross_site_transferring_request.h" | 15 #include "content/browser/frame_host/cross_site_transferring_request.h" |
16 #include "content/browser/frame_host/debug_urls.h" | 16 #include "content/browser/frame_host/debug_urls.h" |
17 #include "content/browser/frame_host/interstitial_page_impl.h" | 17 #include "content/browser/frame_host/interstitial_page_impl.h" |
18 #include "content/browser/frame_host/navigation_before_commit_info.h" | |
18 #include "content/browser/frame_host/navigation_controller_impl.h" | 19 #include "content/browser/frame_host/navigation_controller_impl.h" |
19 #include "content/browser/frame_host/navigation_entry_impl.h" | 20 #include "content/browser/frame_host/navigation_entry_impl.h" |
20 #include "content/browser/frame_host/navigation_request.h" | 21 #include "content/browser/frame_host/navigation_request.h" |
21 #include "content/browser/frame_host/navigation_request_info.h" | 22 #include "content/browser/frame_host/navigation_request_info.h" |
22 #include "content/browser/frame_host/navigator.h" | 23 #include "content/browser/frame_host/navigator.h" |
23 #include "content/browser/frame_host/render_frame_host_factory.h" | 24 #include "content/browser/frame_host/render_frame_host_factory.h" |
24 #include "content/browser/frame_host/render_frame_host_impl.h" | 25 #include "content/browser/frame_host/render_frame_host_impl.h" |
25 #include "content/browser/frame_host/render_frame_proxy_host.h" | 26 #include "content/browser/frame_host/render_frame_proxy_host.h" |
26 #include "content/browser/renderer_host/render_process_host_impl.h" | 27 #include "content/browser/renderer_host/render_process_host_impl.h" |
27 #include "content/browser/renderer_host/render_view_host_factory.h" | 28 #include "content/browser/renderer_host/render_view_host_factory.h" |
28 #include "content/browser/renderer_host/render_view_host_impl.h" | 29 #include "content/browser/renderer_host/render_view_host_impl.h" |
29 #include "content/browser/site_instance_impl.h" | 30 #include "content/browser/site_instance_impl.h" |
30 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 31 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
31 #include "content/browser/webui/web_ui_impl.h" | 32 #include "content/browser/webui/web_ui_impl.h" |
32 #include "content/common/view_messages.h" | 33 #include "content/common/view_messages.h" |
33 #include "content/public/browser/content_browser_client.h" | 34 #include "content/public/browser/content_browser_client.h" |
34 #include "content/public/browser/notification_service.h" | 35 #include "content/public/browser/notification_service.h" |
35 #include "content/public/browser/notification_types.h" | 36 #include "content/public/browser/notification_types.h" |
36 #include "content/public/browser/render_widget_host_iterator.h" | 37 #include "content/public/browser/render_widget_host_iterator.h" |
37 #include "content/public/browser/render_widget_host_view.h" | 38 #include "content/public/browser/render_widget_host_view.h" |
38 #include "content/public/browser/user_metrics.h" | 39 #include "content/public/browser/user_metrics.h" |
39 #include "content/public/browser/web_ui_controller.h" | 40 #include "content/public/browser/web_ui_controller.h" |
40 #include "content/public/common/content_switches.h" | 41 #include "content/public/common/content_switches.h" |
42 #include "content/public/common/referrer.h" | |
41 #include "content/public/common/url_constants.h" | 43 #include "content/public/common/url_constants.h" |
44 #include "net/base/load_flags.h" | |
42 | 45 |
43 namespace content { | 46 namespace content { |
44 | 47 |
48 namespace { | |
49 | |
50 // PlzNavigate | |
51 // Simulates a renderer response to a navigation request when there is no live | |
52 // renderer. | |
53 FrameHostMsg_BeginNavigation_Params BeginNavigationFromNavigate( | |
54 const FrameMsg_Navigate_Params& navigate_params) { | |
55 FrameHostMsg_BeginNavigation_Params begin_navigation_params; | |
56 begin_navigation_params.method = navigate_params.is_post ? | |
57 "POST" : "GET"; | |
nasko
2014/08/13 00:08:00
nit: these should fit in the previous line
clamy
2014/08/13 13:27:24
Done.
| |
58 begin_navigation_params.url = navigate_params.url; | |
59 begin_navigation_params.referrer = | |
60 Referrer(navigate_params.referrer.url, navigate_params.referrer.policy); | |
61 | |
62 // TODO(clamy): This should be modified to take into account caching policy | |
63 // requirements (eg for POST reloads). | |
64 begin_navigation_params.load_flags = | |
65 net::LOAD_NORMAL | net::LOAD_ENABLE_LOAD_TIMING; | |
66 | |
67 // TODO(clamy): Post data from the browser should be put in the request body. | |
68 | |
69 begin_navigation_params.has_user_gesture = false; | |
70 begin_navigation_params.transition_type = navigate_params.transition; | |
71 begin_navigation_params.should_replace_current_entry = | |
72 navigate_params.should_replace_current_entry; | |
73 begin_navigation_params.allow_download = | |
74 navigate_params.allow_download; | |
75 return begin_navigation_params; | |
76 } | |
77 | |
78 } // namespace | |
79 | |
45 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( | 80 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( |
46 const GlobalRequestID& global_request_id, | 81 const GlobalRequestID& global_request_id, |
47 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, | 82 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, |
48 const std::vector<GURL>& transfer_url_chain, | 83 const std::vector<GURL>& transfer_url_chain, |
49 Referrer referrer, | 84 Referrer referrer, |
50 PageTransition page_transition, | 85 PageTransition page_transition, |
51 int render_frame_id, | 86 int render_frame_id, |
52 bool should_replace_current_entry) | 87 bool should_replace_current_entry) |
53 : global_request_id(global_request_id), | 88 : global_request_id(global_request_id), |
54 cross_site_transferring_request(cross_site_transferring_request.Pass()), | 89 cross_site_transferring_request(cross_site_transferring_request.Pass()), |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 // the request. | 258 // the request. |
224 if (pending_nav_params_ && | 259 if (pending_nav_params_ && |
225 pending_nav_params_->global_request_id == | 260 pending_nav_params_->global_request_id == |
226 entry.transferred_global_request_id()) { | 261 entry.transferred_global_request_id()) { |
227 pending_nav_params_->cross_site_transferring_request->ReleaseRequest(); | 262 pending_nav_params_->cross_site_transferring_request->ReleaseRequest(); |
228 } | 263 } |
229 | 264 |
230 return dest_render_frame_host; | 265 return dest_render_frame_host; |
231 } | 266 } |
232 | 267 |
268 // PlzNavigate | |
269 bool RenderFrameHostManager::RequestNavigation( | |
270 const NavigationEntryImpl& entry, | |
271 const FrameMsg_Navigate_Params& navigate_params) { | |
272 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
273 switches::kEnableBrowserSideNavigation)); | |
274 // TODO(clamy): replace RenderViewHost::IsRenderViewLive by | |
275 // RenderFrameHost::IsLive. | |
276 if (render_frame_host_->render_view_host()->IsRenderViewLive()) | |
277 // TODO(clamy): send a RequestNavigation IPC. | |
278 return true; | |
279 | |
280 // The navigation request is sent directly to the IO thread. | |
281 OnBeginNavigation(BeginNavigationFromNavigate(navigate_params), | |
282 entry); | |
283 return true; | |
284 } | |
285 | |
233 void RenderFrameHostManager::Stop() { | 286 void RenderFrameHostManager::Stop() { |
234 render_frame_host_->render_view_host()->Stop(); | 287 render_frame_host_->render_view_host()->Stop(); |
235 | 288 |
236 // If we are cross-navigating, we should stop the pending renderers. This | 289 // If we are cross-navigating, we should stop the pending renderers. This |
237 // will lead to a DidFailProvisionalLoad, which will properly destroy them. | 290 // will lead to a DidFailProvisionalLoad, which will properly destroy them. |
238 if (cross_navigation_pending_) { | 291 if (cross_navigation_pending_) { |
239 pending_render_frame_host_->render_view_host()->Send(new ViewMsg_Stop( | 292 pending_render_frame_host_->render_view_host()->Send(new ViewMsg_Stop( |
240 pending_render_frame_host_->render_view_host()->GetRoutingID())); | 293 pending_render_frame_host_->render_view_host()->GetRoutingID())); |
241 } | 294 } |
242 } | 295 } |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
560 RFHPendingDeleteMap::iterator iter = | 613 RFHPendingDeleteMap::iterator iter = |
561 pending_delete_hosts_.find(site_instance_id); | 614 pending_delete_hosts_.find(site_instance_id); |
562 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) | 615 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) |
563 pending_delete_hosts_.erase(site_instance_id); | 616 pending_delete_hosts_.erase(site_instance_id); |
564 } | 617 } |
565 | 618 |
566 void RenderFrameHostManager::ResetProxyHosts() { | 619 void RenderFrameHostManager::ResetProxyHosts() { |
567 STLDeleteValues(&proxy_hosts_); | 620 STLDeleteValues(&proxy_hosts_); |
568 } | 621 } |
569 | 622 |
623 // PlzNavigate | |
570 void RenderFrameHostManager::OnBeginNavigation( | 624 void RenderFrameHostManager::OnBeginNavigation( |
571 const FrameHostMsg_BeginNavigation_Params& params) { | 625 const FrameHostMsg_BeginNavigation_Params& params, |
626 const NavigationEntryImpl& entry) { | |
627 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
628 switches::kEnableBrowserSideNavigation)); | |
572 // TODO(clamy): Check if navigations are blocked and if so, return | 629 // TODO(clamy): Check if navigations are blocked and if so, return |
573 // immediately. | 630 // immediately. |
574 NavigationRequestInfo info(params); | 631 NavigationRequestInfo info(params); |
575 | 632 |
576 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ? | 633 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ? |
577 params.url : frame_tree_node_->frame_tree()->root()->current_url(); | 634 params.url : frame_tree_node_->frame_tree()->root()->current_url(); |
578 info.is_main_frame = frame_tree_node_->IsMainFrame(); | 635 info.is_main_frame = frame_tree_node_->IsMainFrame(); |
579 info.parent_is_main_frame = !frame_tree_node_->parent() ? | 636 info.parent_is_main_frame = !frame_tree_node_->parent() ? |
580 false : frame_tree_node_->parent()->IsMainFrame(); | 637 false : frame_tree_node_->parent()->IsMainFrame(); |
581 info.is_showing = GetRenderWidgetHostView()->IsShowing(); | 638 info.is_showing = GetRenderWidgetHostView()->IsShowing(); |
582 | 639 |
583 navigation_request_.reset( | 640 // TODO(clamy): Check if the current RFH should be initialized (in case it has |
584 new NavigationRequest(info, frame_tree_node_->frame_tree_node_id())); | 641 // crashed) not to display a sad tab while navigating. |
642 // TODO(clamy): Spawn a speculative renderer process if we do not have one to | |
643 // use for the navigation. | |
644 navigation_request_.reset(new NavigationRequest( | |
645 info, entry, frame_tree_node_->frame_tree_node_id())); | |
585 navigation_request_->BeginNavigation(params.request_body); | 646 navigation_request_->BeginNavigation(params.request_body); |
586 // TODO(clamy): If we have no live RenderFrameHost to handle the request (eg | 647 } |
587 // cross-site navigation) spawn one speculatively here and keep track of it. | 648 |
649 // PlzNavigate | |
650 void RenderFrameHostManager::CommitNavigation( | |
651 const NavigationBeforeCommitInfo& info) { | |
652 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
653 switches::kEnableBrowserSideNavigation)); | |
654 // Update the stored NavigationEntry for commit. | |
655 // TODO(clamy): Check if some more state should be updated at that point. | |
656 navigation_request_->UpdateEntryForCommit(info.navigation_url); | |
657 | |
658 // Pick the right RenderFrameHost to commit the navigation. | |
659 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | |
660 SiteInstance* new_instance = GetSiteInstanceForNavigation( | |
661 navigation_request_->entry()); | |
662 DCHECK(!pending_render_frame_host_.get()); | |
663 | |
664 // TODO(clamy): Update how pending WebUI objects rae handled. | |
Charlie Reis
2014/08/12 19:04:50
nit: are
clamy
2014/08/13 13:27:24
Done.
| |
665 if (current_instance != new_instance) { | |
666 CreateRenderFrameHostForNewSiteInstance( | |
667 current_instance, new_instance, frame_tree_node_->IsMainFrame()); | |
668 DCHECK(pending_render_frame_host_.get()); | |
669 // TODO(clamy): Wait until the navigation has committed before swapping | |
670 // renderers. | |
671 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | |
672 SetRenderFrameHost(pending_render_frame_host_.Pass()); | |
673 if (frame_tree_node_->IsMainFrame()) | |
674 render_frame_host_->render_view_host()->AttachToFrameTree(); | |
675 } | |
676 | |
677 frame_tree_node_->navigator()->CommitNavigation( | |
678 render_frame_host_.get(), info); | |
679 navigation_request_.reset(); | |
588 } | 680 } |
589 | 681 |
590 void RenderFrameHostManager::Observe( | 682 void RenderFrameHostManager::Observe( |
591 int type, | 683 int type, |
592 const NotificationSource& source, | 684 const NotificationSource& source, |
593 const NotificationDetails& details) { | 685 const NotificationDetails& details) { |
594 switch (type) { | 686 switch (type) { |
595 case NOTIFICATION_RENDERER_PROCESS_CLOSED: | 687 case NOTIFICATION_RENDERER_PROCESS_CLOSED: |
596 case NOTIFICATION_RENDERER_PROCESS_CLOSING: | 688 case NOTIFICATION_RENDERER_PROCESS_CLOSING: |
597 RendererProcessClosing( | 689 RendererProcessClosing( |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 const NavigationEntryImpl* new_entry) const { | 816 const NavigationEntryImpl* new_entry) const { |
725 NavigationControllerImpl& controller = | 817 NavigationControllerImpl& controller = |
726 delegate_->GetControllerForRenderManager(); | 818 delegate_->GetControllerForRenderManager(); |
727 return current_entry && web_ui_.get() && | 819 return current_entry && web_ui_.get() && |
728 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 820 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
729 controller.GetBrowserContext(), current_entry->GetURL()) == | 821 controller.GetBrowserContext(), current_entry->GetURL()) == |
730 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 822 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
731 controller.GetBrowserContext(), new_entry->GetURL())); | 823 controller.GetBrowserContext(), new_entry->GetURL())); |
732 } | 824 } |
733 | 825 |
826 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( | |
827 const NavigationEntryImpl& entry) { | |
828 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | |
829 SiteInstance* new_instance = current_instance; | |
830 | |
831 // We do not currently swap processes for navigations in webview tag guests. | |
832 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); | |
833 | |
834 // Determine if we need a new BrowsingInstance for this entry. If true, this | |
835 // implies that it will get a new SiteInstance (and likely process), and that | |
836 // other tabs in the current BrowsingInstance will be unable to script it. | |
837 // This is used for cases that require a process swap even in the | |
838 // process-per-tab model, such as WebUI pages. | |
839 const NavigationEntry* current_entry = | |
840 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
841 bool force_swap = !is_guest_scheme && | |
842 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry); | |
843 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) | |
844 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap); | |
845 | |
846 // If force_swap is true, we must use a different SiteInstance. If we didn't, | |
847 // we would have two RenderFrameHosts in the same SiteInstance and the same | |
848 // frame, resulting in page_id conflicts for their NavigationEntries. | |
849 if (force_swap) | |
850 CHECK_NE(new_instance, current_instance); | |
851 | |
852 return new_instance; | |
853 } | |
854 | |
734 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry( | 855 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry( |
735 const NavigationEntryImpl& entry, | 856 const NavigationEntryImpl& entry, |
736 SiteInstance* current_instance, | 857 SiteInstance* current_instance, |
737 bool force_browsing_instance_swap) { | 858 bool force_browsing_instance_swap) { |
738 // Determine which SiteInstance to use for navigating to |entry|. | 859 // Determine which SiteInstance to use for navigating to |entry|. |
739 const GURL& dest_url = entry.GetURL(); | 860 const GURL& dest_url = entry.GetURL(); |
740 NavigationControllerImpl& controller = | 861 NavigationControllerImpl& controller = |
741 delegate_->GetControllerForRenderManager(); | 862 delegate_->GetControllerForRenderManager(); |
742 BrowserContext* browser_context = controller.GetBrowserContext(); | 863 BrowserContext* browser_context = controller.GetBrowserContext(); |
743 | 864 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
891 } | 1012 } |
892 | 1013 |
893 // Start the new renderer in a new SiteInstance, but in the current | 1014 // Start the new renderer in a new SiteInstance, but in the current |
894 // BrowsingInstance. It is important to immediately give this new | 1015 // BrowsingInstance. It is important to immediately give this new |
895 // SiteInstance to a RenderViewHost (if it is different than our current | 1016 // SiteInstance to a RenderViewHost (if it is different than our current |
896 // SiteInstance), so that it is ref counted. This will happen in | 1017 // SiteInstance), so that it is ref counted. This will happen in |
897 // CreateRenderView. | 1018 // CreateRenderView. |
898 return current_instance->GetRelatedSiteInstance(dest_url); | 1019 return current_instance->GetRelatedSiteInstance(dest_url); |
899 } | 1020 } |
900 | 1021 |
1022 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( | |
1023 SiteInstance* old_instance, | |
1024 SiteInstance* new_instance, | |
1025 bool is_main_frame) { | |
1026 // Ensure that we have created RFHs for the new RFH's opener chain if | |
1027 // we are staying in the same BrowsingInstance. This allows the new RFH | |
1028 // to send cross-process script calls to its opener(s). | |
1029 int opener_route_id = MSG_ROUTING_NONE; | |
1030 if (new_instance->IsRelatedSiteInstance(old_instance)) { | |
1031 opener_route_id = | |
1032 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | |
1033 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
1034 switches::kSitePerProcess)) { | |
1035 // Ensure that the frame tree has RenderFrameProxyHosts for the new | |
1036 // SiteInstance in all nodes except the current one. | |
1037 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | |
1038 frame_tree_node_, new_instance); | |
1039 } | |
1040 } | |
1041 | |
1042 // Create a non-swapped-out RFH with the given opener. | |
1043 int route_id = CreateRenderFrame( | |
1044 new_instance, opener_route_id, false, is_main_frame, | |
1045 delegate_->IsHidden()); | |
1046 if (route_id == MSG_ROUTING_NONE) { | |
1047 pending_render_frame_host_.reset(); | |
1048 return; | |
1049 } | |
1050 } | |
1051 | |
901 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 1052 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( |
902 SiteInstance* site_instance, | 1053 SiteInstance* site_instance, |
903 int view_routing_id, | 1054 int view_routing_id, |
904 int frame_routing_id, | 1055 int frame_routing_id, |
905 bool swapped_out, | 1056 bool swapped_out, |
906 bool hidden) { | 1057 bool hidden) { |
907 if (frame_routing_id == MSG_ROUTING_NONE) | 1058 if (frame_routing_id == MSG_ROUTING_NONE) |
908 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 1059 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
909 | 1060 |
910 // Create a RVH for main frames, or find the existing one for subframes. | 1061 // Create a RVH for main frames, or find the existing one for subframes. |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1317 const NavigationEntryImpl& entry) { | 1468 const NavigationEntryImpl& entry) { |
1318 // If we are currently navigating cross-process, we want to get back to normal | 1469 // If we are currently navigating cross-process, we want to get back to normal |
1319 // and then navigate as usual. | 1470 // and then navigate as usual. |
1320 if (cross_navigation_pending_) { | 1471 if (cross_navigation_pending_) { |
1321 if (pending_render_frame_host_) | 1472 if (pending_render_frame_host_) |
1322 CancelPending(); | 1473 CancelPending(); |
1323 cross_navigation_pending_ = false; | 1474 cross_navigation_pending_ = false; |
1324 } | 1475 } |
1325 | 1476 |
1326 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1477 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
1327 scoped_refptr<SiteInstance> new_instance = current_instance; | 1478 scoped_refptr<SiteInstance> new_instance = |
1479 GetSiteInstanceForNavigation(entry); | |
1328 | 1480 |
1329 // We do not currently swap processes for navigations in webview tag guests. | |
1330 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); | |
1331 | |
1332 // Determine if we need a new BrowsingInstance for this entry. If true, this | |
1333 // implies that it will get a new SiteInstance (and likely process), and that | |
1334 // other tabs in the current BrowsingInstance will be unable to script it. | |
1335 // This is used for cases that require a process swap even in the | |
1336 // process-per-tab model, such as WebUI pages. | |
1337 const NavigationEntry* current_entry = | 1481 const NavigationEntry* current_entry = |
1338 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1482 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
1339 bool force_swap = !is_guest_scheme && | |
1340 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry); | |
1341 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) | |
1342 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap); | |
1343 | |
1344 // If force_swap is true, we must use a different SiteInstance. If we didn't, | |
1345 // we would have two RenderFrameHosts in the same SiteInstance and the same | |
1346 // frame, resulting in page_id conflicts for their NavigationEntries. | |
1347 if (force_swap) | |
1348 CHECK_NE(new_instance, current_instance); | |
1349 | 1483 |
1350 if (new_instance != current_instance) { | 1484 if (new_instance != current_instance) { |
1351 // New SiteInstance: create a pending RFH to navigate. | 1485 // New SiteInstance: create a pending RFH to navigate. |
1352 DCHECK(!cross_navigation_pending_); | 1486 DCHECK(!cross_navigation_pending_); |
1353 | 1487 |
1354 // This will possibly create (set to NULL) a Web UI object for the pending | 1488 // This will possibly create (set to NULL) a Web UI object for the pending |
1355 // page. We'll use this later to give the page special access. This must | 1489 // page. We'll use this later to give the page special access. This must |
1356 // happen before the new renderer is created below so it will get bindings. | 1490 // happen before the new renderer is created below so it will get bindings. |
1357 // It must also happen after the above conditional call to CancelPending(), | 1491 // It must also happen after the above conditional call to CancelPending(), |
1358 // otherwise CancelPending may clear the pending_web_ui_ and the page will | 1492 // otherwise CancelPending may clear the pending_web_ui_ and the page will |
1359 // not have its bindings set appropriately. | 1493 // not have its bindings set appropriately. |
1360 SetPendingWebUI(entry); | 1494 SetPendingWebUI(entry); |
1361 | 1495 CreateRenderFrameHostForNewSiteInstance( |
1362 // Ensure that we have created RFHs for the new RFH's opener chain if | 1496 current_instance, new_instance, frame_tree_node_->IsMainFrame()); |
1363 // we are staying in the same BrowsingInstance. This allows the pending RFH | 1497 if (!pending_render_frame_host_.get()) { |
1364 // to send cross-process script calls to its opener(s). | 1498 return NULL; |
1365 int opener_route_id = MSG_ROUTING_NONE; | |
1366 if (new_instance->IsRelatedSiteInstance(current_instance)) { | |
1367 opener_route_id = | |
1368 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | |
1369 | |
1370 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
1371 switches::kSitePerProcess)) { | |
1372 // Ensure that the frame tree has RenderFrameProxyHosts for the new | |
1373 // SiteInstance in all nodes except the current one. | |
1374 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | |
1375 frame_tree_node_, new_instance); | |
1376 } | |
1377 } | 1499 } |
1378 | 1500 |
1379 // Create a non-swapped-out pending RFH with the given opener and navigate | |
1380 // it. | |
1381 int route_id = CreateRenderFrame(new_instance, | |
1382 opener_route_id, | |
1383 false, | |
1384 frame_tree_node_->IsMainFrame(), | |
1385 delegate_->IsHidden()); | |
1386 if (route_id == MSG_ROUTING_NONE) | |
1387 return NULL; | |
1388 | |
1389 // Check if our current RFH is live before we set up a transition. | 1501 // Check if our current RFH is live before we set up a transition. |
1390 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | 1502 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { |
1391 if (!cross_navigation_pending_) { | 1503 if (!cross_navigation_pending_) { |
1392 // The current RFH is not live. There's no reason to sit around with a | 1504 // The current RFH is not live. There's no reason to sit around with a |
1393 // sad tab or a newly created RFH while we wait for the pending RFH to | 1505 // sad tab or a newly created RFH while we wait for the pending RFH to |
1394 // navigate. Just switch to the pending RFH now and go back to non | 1506 // navigate. Just switch to the pending RFH now and go back to non |
1395 // cross-navigating (Note that we don't care about on{before}unload | 1507 // cross-navigating (Note that we don't care about on{before}unload |
1396 // handlers if the current RFH isn't live.) | 1508 // handlers if the current RFH isn't live.) |
1397 CommitPending(); | 1509 CommitPending(); |
1398 return render_frame_host_.get(); | 1510 return render_frame_host_.get(); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1597 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1709 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
1598 SiteInstance* instance) { | 1710 SiteInstance* instance) { |
1599 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1711 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
1600 if (iter != proxy_hosts_.end()) { | 1712 if (iter != proxy_hosts_.end()) { |
1601 delete iter->second; | 1713 delete iter->second; |
1602 proxy_hosts_.erase(iter); | 1714 proxy_hosts_.erase(iter); |
1603 } | 1715 } |
1604 } | 1716 } |
1605 | 1717 |
1606 } // namespace content | 1718 } // namespace content |
OLD | NEW |