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 ? "POST" : "GET"; |
| 57 begin_navigation_params.url = navigate_params.url; |
| 58 begin_navigation_params.referrer = |
| 59 Referrer(navigate_params.referrer.url, navigate_params.referrer.policy); |
| 60 |
| 61 // TODO(clamy): This should be modified to take into account caching policy |
| 62 // requirements (eg for POST reloads). |
| 63 begin_navigation_params.load_flags = net::LOAD_NORMAL; |
| 64 |
| 65 // TODO(clamy): Post data from the browser should be put in the request body. |
| 66 |
| 67 begin_navigation_params.has_user_gesture = false; |
| 68 begin_navigation_params.transition_type = navigate_params.transition; |
| 69 begin_navigation_params.should_replace_current_entry = |
| 70 navigate_params.should_replace_current_entry; |
| 71 begin_navigation_params.allow_download = |
| 72 navigate_params.allow_download; |
| 73 return begin_navigation_params; |
| 74 } |
| 75 |
| 76 } // namespace |
| 77 |
45 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( | 78 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( |
46 const GlobalRequestID& global_request_id, | 79 const GlobalRequestID& global_request_id, |
47 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, | 80 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, |
48 const std::vector<GURL>& transfer_url_chain, | 81 const std::vector<GURL>& transfer_url_chain, |
49 Referrer referrer, | 82 Referrer referrer, |
50 PageTransition page_transition, | 83 PageTransition page_transition, |
51 int render_frame_id, | 84 int render_frame_id, |
52 bool should_replace_current_entry) | 85 bool should_replace_current_entry) |
53 : global_request_id(global_request_id), | 86 : global_request_id(global_request_id), |
54 cross_site_transferring_request(cross_site_transferring_request.Pass()), | 87 cross_site_transferring_request(cross_site_transferring_request.Pass()), |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 RFHPendingDeleteMap::iterator iter = | 589 RFHPendingDeleteMap::iterator iter = |
557 pending_delete_hosts_.find(site_instance_id); | 590 pending_delete_hosts_.find(site_instance_id); |
558 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) | 591 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) |
559 pending_delete_hosts_.erase(site_instance_id); | 592 pending_delete_hosts_.erase(site_instance_id); |
560 } | 593 } |
561 | 594 |
562 void RenderFrameHostManager::ResetProxyHosts() { | 595 void RenderFrameHostManager::ResetProxyHosts() { |
563 STLDeleteValues(&proxy_hosts_); | 596 STLDeleteValues(&proxy_hosts_); |
564 } | 597 } |
565 | 598 |
| 599 // PlzNavigate |
| 600 bool RenderFrameHostManager::RequestNavigation( |
| 601 const NavigationEntryImpl& entry, |
| 602 const FrameMsg_Navigate_Params& navigate_params) { |
| 603 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 604 switches::kEnableBrowserSideNavigation)); |
| 605 // TODO(clamy): replace RenderViewHost::IsRenderViewLive by |
| 606 // RenderFrameHost::IsLive. |
| 607 if (render_frame_host_->render_view_host()->IsRenderViewLive()) |
| 608 // TODO(clamy): send a RequestNavigation IPC. |
| 609 return true; |
| 610 |
| 611 // The navigation request is sent directly to the IO thread. |
| 612 OnBeginNavigation(BeginNavigationFromNavigate(navigate_params)); |
| 613 return true; |
| 614 } |
| 615 |
| 616 // PlzNavigate |
566 void RenderFrameHostManager::OnBeginNavigation( | 617 void RenderFrameHostManager::OnBeginNavigation( |
567 const FrameHostMsg_BeginNavigation_Params& params) { | 618 const FrameHostMsg_BeginNavigation_Params& params) { |
| 619 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 620 switches::kEnableBrowserSideNavigation)); |
568 // TODO(clamy): Check if navigations are blocked and if so, return | 621 // TODO(clamy): Check if navigations are blocked and if so, return |
569 // immediately. | 622 // immediately. |
570 NavigationRequestInfo info(params); | 623 NavigationRequestInfo info(params); |
571 | 624 |
572 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ? | 625 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ? |
573 params.url : frame_tree_node_->frame_tree()->root()->current_url(); | 626 params.url : frame_tree_node_->frame_tree()->root()->current_url(); |
574 info.is_main_frame = frame_tree_node_->IsMainFrame(); | 627 info.is_main_frame = frame_tree_node_->IsMainFrame(); |
575 info.parent_is_main_frame = !frame_tree_node_->parent() ? | 628 info.parent_is_main_frame = !frame_tree_node_->parent() ? |
576 false : frame_tree_node_->parent()->IsMainFrame(); | 629 false : frame_tree_node_->parent()->IsMainFrame(); |
577 info.is_showing = GetRenderWidgetHostView()->IsShowing(); | 630 info.is_showing = GetRenderWidgetHostView()->IsShowing(); |
578 | 631 |
579 navigation_request_.reset( | 632 // TODO(clamy): Check if the current RFH should be initialized (in case it has |
580 new NavigationRequest(info, frame_tree_node_->frame_tree_node_id())); | 633 // crashed) not to display a sad tab while navigating. |
| 634 // TODO(clamy): Spawn a speculative renderer process if we do not have one to |
| 635 // use for the navigation. |
| 636 navigation_request_.reset(new NavigationRequest( |
| 637 info, frame_tree_node_->frame_tree_node_id())); |
581 navigation_request_->BeginNavigation(params.request_body); | 638 navigation_request_->BeginNavigation(params.request_body); |
582 // TODO(clamy): If we have no live RenderFrameHost to handle the request (eg | 639 } |
583 // cross-site navigation) spawn one speculatively here and keep track of it. | 640 |
| 641 // PlzNavigate |
| 642 void RenderFrameHostManager::CommitNavigation( |
| 643 const NavigationBeforeCommitInfo& info) { |
| 644 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 645 switches::kEnableBrowserSideNavigation)); |
| 646 // Pick the right RenderFrameHost to commit the navigation. |
| 647 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 648 // TODO(clamy): Replace the default values by the right ones. This may require |
| 649 // some storing in RequestNavigation. |
| 650 SiteInstance* new_instance = GetSiteInstanceForNavigation( |
| 651 info.navigation_url, |
| 652 NULL, |
| 653 navigation_request_->info().navigation_params.transition_type, |
| 654 false, |
| 655 false); |
| 656 DCHECK(!pending_render_frame_host_.get()); |
| 657 |
| 658 // TODO(clamy): Update how pending WebUI objects are handled. |
| 659 if (current_instance != new_instance) { |
| 660 CreateRenderFrameHostForNewSiteInstance( |
| 661 current_instance, new_instance, frame_tree_node_->IsMainFrame()); |
| 662 DCHECK(pending_render_frame_host_.get()); |
| 663 // TODO(clamy): Wait until the navigation has committed before swapping |
| 664 // renderers. |
| 665 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 666 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
| 667 if (frame_tree_node_->IsMainFrame()) |
| 668 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 669 } |
| 670 |
| 671 frame_tree_node_->navigator()->CommitNavigation( |
| 672 render_frame_host_.get(), info); |
584 } | 673 } |
585 | 674 |
586 void RenderFrameHostManager::Observe( | 675 void RenderFrameHostManager::Observe( |
587 int type, | 676 int type, |
588 const NotificationSource& source, | 677 const NotificationSource& source, |
589 const NotificationDetails& details) { | 678 const NotificationDetails& details) { |
590 switch (type) { | 679 switch (type) { |
591 case NOTIFICATION_RENDERER_PROCESS_CLOSED: | 680 case NOTIFICATION_RENDERER_PROCESS_CLOSED: |
592 case NOTIFICATION_RENDERER_PROCESS_CLOSING: | 681 case NOTIFICATION_RENDERER_PROCESS_CLOSING: |
593 RendererProcessClosing( | 682 RendererProcessClosing( |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 const NavigationEntryImpl* new_entry) const { | 799 const NavigationEntryImpl* new_entry) const { |
711 NavigationControllerImpl& controller = | 800 NavigationControllerImpl& controller = |
712 delegate_->GetControllerForRenderManager(); | 801 delegate_->GetControllerForRenderManager(); |
713 return current_entry && web_ui_.get() && | 802 return current_entry && web_ui_.get() && |
714 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 803 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
715 controller.GetBrowserContext(), current_entry->GetURL()) == | 804 controller.GetBrowserContext(), current_entry->GetURL()) == |
716 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 805 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
717 controller.GetBrowserContext(), new_entry->GetURL())); | 806 controller.GetBrowserContext(), new_entry->GetURL())); |
718 } | 807 } |
719 | 808 |
| 809 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
| 810 const GURL& dest_url, |
| 811 SiteInstance* dest_instance, |
| 812 PageTransition dest_transition, |
| 813 bool dest_is_restore, |
| 814 bool dest_is_view_source_mode) { |
| 815 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 816 SiteInstance* new_instance = current_instance; |
| 817 |
| 818 // We do not currently swap processes for navigations in webview tag guests. |
| 819 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); |
| 820 |
| 821 // Determine if we need a new BrowsingInstance for this entry. If true, this |
| 822 // implies that it will get a new SiteInstance (and likely process), and that |
| 823 // other tabs in the current BrowsingInstance will be unable to script it. |
| 824 // This is used for cases that require a process swap even in the |
| 825 // process-per-tab model, such as WebUI pages. |
| 826 // TODO(clamy): Remove the dependency on the current entry. |
| 827 const NavigationEntry* current_entry = |
| 828 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
| 829 BrowserContext* browser_context = |
| 830 delegate_->GetControllerForRenderManager().GetBrowserContext(); |
| 831 const GURL& current_effective_url = current_entry ? |
| 832 SiteInstanceImpl::GetEffectiveURL(browser_context, |
| 833 current_entry->GetURL()) : |
| 834 render_frame_host_->GetSiteInstance()->GetSiteURL(); |
| 835 bool current_is_view_source_mode = current_entry ? |
| 836 current_entry->IsViewSourceMode() : dest_is_view_source_mode; |
| 837 bool force_swap = !is_guest_scheme && |
| 838 ShouldSwapBrowsingInstancesForNavigation( |
| 839 current_effective_url, |
| 840 current_is_view_source_mode, |
| 841 dest_instance, |
| 842 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), |
| 843 dest_is_view_source_mode); |
| 844 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) { |
| 845 new_instance = GetSiteInstanceForURL( |
| 846 dest_url, |
| 847 dest_instance, |
| 848 dest_transition, |
| 849 dest_is_restore, |
| 850 dest_is_view_source_mode, |
| 851 current_instance, |
| 852 force_swap); |
| 853 } |
| 854 |
| 855 // If force_swap is true, we must use a different SiteInstance. If we didn't, |
| 856 // we would have two RenderFrameHosts in the same SiteInstance and the same |
| 857 // frame, resulting in page_id conflicts for their NavigationEntries. |
| 858 if (force_swap) |
| 859 CHECK_NE(new_instance, current_instance); |
| 860 return new_instance; |
| 861 } |
| 862 |
720 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( | 863 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( |
721 const GURL& dest_url, | 864 const GURL& dest_url, |
722 SiteInstance* dest_instance, | 865 SiteInstance* dest_instance, |
723 PageTransition dest_transition, | 866 PageTransition dest_transition, |
724 bool dest_is_restore, | 867 bool dest_is_restore, |
725 bool dest_is_view_source_mode, | 868 bool dest_is_view_source_mode, |
726 SiteInstance* current_instance, | 869 SiteInstance* current_instance, |
727 bool force_browsing_instance_swap) { | 870 bool force_browsing_instance_swap) { |
728 NavigationControllerImpl& controller = | 871 NavigationControllerImpl& controller = |
729 delegate_->GetControllerForRenderManager(); | 872 delegate_->GetControllerForRenderManager(); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 } | 1021 } |
879 | 1022 |
880 // Start the new renderer in a new SiteInstance, but in the current | 1023 // Start the new renderer in a new SiteInstance, but in the current |
881 // BrowsingInstance. It is important to immediately give this new | 1024 // BrowsingInstance. It is important to immediately give this new |
882 // SiteInstance to a RenderViewHost (if it is different than our current | 1025 // SiteInstance to a RenderViewHost (if it is different than our current |
883 // SiteInstance), so that it is ref counted. This will happen in | 1026 // SiteInstance), so that it is ref counted. This will happen in |
884 // CreateRenderView. | 1027 // CreateRenderView. |
885 return current_instance->GetRelatedSiteInstance(dest_url); | 1028 return current_instance->GetRelatedSiteInstance(dest_url); |
886 } | 1029 } |
887 | 1030 |
| 1031 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( |
| 1032 SiteInstance* old_instance, |
| 1033 SiteInstance* new_instance, |
| 1034 bool is_main_frame) { |
| 1035 // Ensure that we have created RFHs for the new RFH's opener chain if |
| 1036 // we are staying in the same BrowsingInstance. This allows the new RFH |
| 1037 // to send cross-process script calls to its opener(s). |
| 1038 int opener_route_id = MSG_ROUTING_NONE; |
| 1039 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
| 1040 opener_route_id = |
| 1041 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); |
| 1042 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 1043 switches::kSitePerProcess)) { |
| 1044 // Ensure that the frame tree has RenderFrameProxyHosts for the new |
| 1045 // SiteInstance in all nodes except the current one. |
| 1046 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( |
| 1047 frame_tree_node_, new_instance); |
| 1048 } |
| 1049 } |
| 1050 |
| 1051 // Create a non-swapped-out RFH with the given opener. |
| 1052 int route_id = CreateRenderFrame( |
| 1053 new_instance, opener_route_id, false, is_main_frame, |
| 1054 delegate_->IsHidden()); |
| 1055 if (route_id == MSG_ROUTING_NONE) { |
| 1056 pending_render_frame_host_.reset(); |
| 1057 return; |
| 1058 } |
| 1059 } |
| 1060 |
888 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 1061 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( |
889 SiteInstance* site_instance, | 1062 SiteInstance* site_instance, |
890 int view_routing_id, | 1063 int view_routing_id, |
891 int frame_routing_id, | 1064 int frame_routing_id, |
892 bool swapped_out, | 1065 bool swapped_out, |
893 bool hidden) { | 1066 bool hidden) { |
894 if (frame_routing_id == MSG_ROUTING_NONE) | 1067 if (frame_routing_id == MSG_ROUTING_NONE) |
895 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 1068 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
896 | 1069 |
897 // Create a RVH for main frames, or find the existing one for subframes. | 1070 // 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... |
1304 const NavigationEntryImpl& entry) { | 1477 const NavigationEntryImpl& entry) { |
1305 // If we are currently navigating cross-process, we want to get back to normal | 1478 // If we are currently navigating cross-process, we want to get back to normal |
1306 // and then navigate as usual. | 1479 // and then navigate as usual. |
1307 if (cross_navigation_pending_) { | 1480 if (cross_navigation_pending_) { |
1308 if (pending_render_frame_host_) | 1481 if (pending_render_frame_host_) |
1309 CancelPending(); | 1482 CancelPending(); |
1310 cross_navigation_pending_ = false; | 1483 cross_navigation_pending_ = false; |
1311 } | 1484 } |
1312 | 1485 |
1313 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1486 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
1314 scoped_refptr<SiteInstance> new_instance = current_instance; | 1487 scoped_refptr<SiteInstance> new_instance = |
| 1488 GetSiteInstanceForNavigation( |
| 1489 entry.GetURL(), |
| 1490 entry.site_instance(), |
| 1491 entry.GetTransitionType(), |
| 1492 entry.restore_type() != NavigationEntryImpl::RESTORE_NONE, |
| 1493 entry.IsViewSourceMode()); |
1315 | 1494 |
1316 // We do not currently swap processes for navigations in webview tag guests. | |
1317 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme); | |
1318 | |
1319 // Determine if we need a new BrowsingInstance for this entry. If true, this | |
1320 // implies that it will get a new SiteInstance (and likely process), and that | |
1321 // other tabs in the current BrowsingInstance will be unable to script it. | |
1322 // This is used for cases that require a process swap even in the | |
1323 // process-per-tab model, such as WebUI pages. | |
1324 const NavigationEntry* current_entry = | 1495 const NavigationEntry* current_entry = |
1325 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1496 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
1326 BrowserContext* browser_context = | |
1327 delegate_->GetControllerForRenderManager().GetBrowserContext(); | |
1328 const GURL& current_effective_url = current_entry ? | |
1329 SiteInstanceImpl::GetEffectiveURL(browser_context, | |
1330 current_entry->GetURL()) : | |
1331 render_frame_host_->GetSiteInstance()->GetSiteURL(); | |
1332 bool current_is_view_source_mode = current_entry ? | |
1333 current_entry->IsViewSourceMode() : entry.IsViewSourceMode(); | |
1334 bool force_swap = !is_guest_scheme && | |
1335 ShouldSwapBrowsingInstancesForNavigation( | |
1336 current_effective_url, | |
1337 current_is_view_source_mode, | |
1338 entry.site_instance(), | |
1339 SiteInstanceImpl::GetEffectiveURL(browser_context, entry.GetURL()), | |
1340 entry.IsViewSourceMode()); | |
1341 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) { | |
1342 new_instance = GetSiteInstanceForURL( | |
1343 entry.GetURL(), | |
1344 entry.site_instance(), | |
1345 entry.GetTransitionType(), | |
1346 entry.restore_type() != NavigationEntryImpl::RESTORE_NONE, | |
1347 entry.IsViewSourceMode(), | |
1348 current_instance, | |
1349 force_swap); | |
1350 } | |
1351 | |
1352 // If force_swap is true, we must use a different SiteInstance. If we didn't, | |
1353 // we would have two RenderFrameHosts in the same SiteInstance and the same | |
1354 // frame, resulting in page_id conflicts for their NavigationEntries. | |
1355 if (force_swap) | |
1356 CHECK_NE(new_instance, current_instance); | |
1357 | 1497 |
1358 if (new_instance != current_instance) { | 1498 if (new_instance != current_instance) { |
1359 // New SiteInstance: create a pending RFH to navigate. | 1499 // New SiteInstance: create a pending RFH to navigate. |
1360 DCHECK(!cross_navigation_pending_); | 1500 DCHECK(!cross_navigation_pending_); |
1361 | 1501 |
1362 // This will possibly create (set to NULL) a Web UI object for the pending | 1502 // This will possibly create (set to NULL) a Web UI object for the pending |
1363 // page. We'll use this later to give the page special access. This must | 1503 // page. We'll use this later to give the page special access. This must |
1364 // happen before the new renderer is created below so it will get bindings. | 1504 // happen before the new renderer is created below so it will get bindings. |
1365 // It must also happen after the above conditional call to CancelPending(), | 1505 // It must also happen after the above conditional call to CancelPending(), |
1366 // otherwise CancelPending may clear the pending_web_ui_ and the page will | 1506 // otherwise CancelPending may clear the pending_web_ui_ and the page will |
1367 // not have its bindings set appropriately. | 1507 // not have its bindings set appropriately. |
1368 SetPendingWebUI(entry); | 1508 SetPendingWebUI(entry); |
1369 | 1509 CreateRenderFrameHostForNewSiteInstance( |
1370 // Ensure that we have created RFHs for the new RFH's opener chain if | 1510 current_instance, new_instance, frame_tree_node_->IsMainFrame()); |
1371 // we are staying in the same BrowsingInstance. This allows the pending RFH | 1511 if (!pending_render_frame_host_.get()) { |
1372 // to send cross-process script calls to its opener(s). | 1512 return NULL; |
1373 int opener_route_id = MSG_ROUTING_NONE; | |
1374 if (new_instance->IsRelatedSiteInstance(current_instance)) { | |
1375 opener_route_id = | |
1376 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | |
1377 | |
1378 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
1379 switches::kSitePerProcess)) { | |
1380 // Ensure that the frame tree has RenderFrameProxyHosts for the new | |
1381 // SiteInstance in all nodes except the current one. | |
1382 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | |
1383 frame_tree_node_, new_instance); | |
1384 } | |
1385 } | 1513 } |
1386 | 1514 |
1387 // Create a non-swapped-out pending RFH with the given opener and navigate | |
1388 // it. | |
1389 int route_id = CreateRenderFrame(new_instance, | |
1390 opener_route_id, | |
1391 false, | |
1392 frame_tree_node_->IsMainFrame(), | |
1393 delegate_->IsHidden()); | |
1394 if (route_id == MSG_ROUTING_NONE) | |
1395 return NULL; | |
1396 | |
1397 // Check if our current RFH is live before we set up a transition. | 1515 // Check if our current RFH is live before we set up a transition. |
1398 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | 1516 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { |
1399 if (!cross_navigation_pending_) { | 1517 if (!cross_navigation_pending_) { |
1400 // The current RFH is not live. There's no reason to sit around with a | 1518 // The current RFH is not live. There's no reason to sit around with a |
1401 // sad tab or a newly created RFH while we wait for the pending RFH to | 1519 // sad tab or a newly created RFH while we wait for the pending RFH to |
1402 // navigate. Just switch to the pending RFH now and go back to non | 1520 // navigate. Just switch to the pending RFH now and go back to non |
1403 // cross-navigating (Note that we don't care about on{before}unload | 1521 // cross-navigating (Note that we don't care about on{before}unload |
1404 // handlers if the current RFH isn't live.) | 1522 // handlers if the current RFH isn't live.) |
1405 CommitPending(); | 1523 CommitPending(); |
1406 return render_frame_host_.get(); | 1524 return render_frame_host_.get(); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1602 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1720 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
1603 SiteInstance* instance) { | 1721 SiteInstance* instance) { |
1604 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1722 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
1605 if (iter != proxy_hosts_.end()) { | 1723 if (iter != proxy_hosts_.end()) { |
1606 delete iter->second; | 1724 delete iter->second; |
1607 proxy_hosts_.erase(iter); | 1725 proxy_hosts_.erase(iter); |
1608 } | 1726 } |
1609 } | 1727 } |
1610 | 1728 |
1611 } // namespace content | 1729 } // namespace content |
OLD | NEW |