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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
725 pending_render_frame_host_->ClearAllWebUI(); | 725 pending_render_frame_host_->ClearAllWebUI(); |
726 // PlzNavigate | 726 // PlzNavigate |
727 if (speculative_render_frame_host_) | 727 if (speculative_render_frame_host_) |
728 speculative_render_frame_host_->ClearAllWebUI(); | 728 speculative_render_frame_host_->ClearAllWebUI(); |
729 } | 729 } |
730 | 730 |
731 // PlzNavigate | 731 // PlzNavigate |
732 void RenderFrameHostManager::DidCreateNavigationRequest( | 732 void RenderFrameHostManager::DidCreateNavigationRequest( |
733 NavigationRequest* request) { | 733 NavigationRequest* request) { |
734 CHECK(IsBrowserSideNavigationEnabled()); | 734 CHECK(IsBrowserSideNavigationEnabled()); |
735 RenderFrameHostImpl* dest_rfh = GetFrameHostForNavigation(*request); | 735 RenderFrameHostImpl* dest_rfh = GetFrameHostForNavigation(request, false); |
736 DCHECK(dest_rfh); | 736 DCHECK(dest_rfh); |
737 request->set_associated_site_instance_type( | |
738 dest_rfh == render_frame_host_.get() | |
739 ? NavigationRequest::AssociatedSiteInstanceType::CURRENT | |
740 : NavigationRequest::AssociatedSiteInstanceType::SPECULATIVE); | |
741 } | 737 } |
742 | 738 |
743 // PlzNavigate | 739 // PlzNavigate |
744 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 740 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
745 const NavigationRequest& request) { | 741 NavigationRequest* request, |
742 bool is_commit) { | |
746 CHECK(IsBrowserSideNavigationEnabled()); | 743 CHECK(IsBrowserSideNavigationEnabled()); |
744 DCHECK(request); | |
747 | 745 |
748 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); | 746 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); |
749 | 747 |
750 SiteInstance* candidate_site_instance = | 748 SiteInstance* candidate_site_instance = |
751 speculative_render_frame_host_ | 749 speculative_render_frame_host_ |
752 ? speculative_render_frame_host_->GetSiteInstance() | 750 ? speculative_render_frame_host_->GetSiteInstance() |
753 : nullptr; | 751 : nullptr; |
754 | 752 |
755 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation( | 753 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation( |
756 request.common_params().url, request.source_site_instance(), | 754 request->common_params().url, request->source_site_instance(), |
757 request.dest_site_instance(), candidate_site_instance, | 755 request->dest_site_instance(), candidate_site_instance, |
758 request.common_params().transition, | 756 request->common_params().transition, |
759 request.restore_type() != NavigationEntryImpl::RESTORE_NONE, | 757 request->restore_type() != NavigationEntryImpl::RESTORE_NONE, |
760 request.is_view_source()); | 758 request->is_view_source()); |
761 | 759 |
762 // The appropriate RenderFrameHost to commit the navigation. | 760 // The appropriate RenderFrameHost to commit the navigation. |
763 RenderFrameHostImpl* navigation_rfh = nullptr; | 761 RenderFrameHostImpl* navigation_rfh = nullptr; |
764 | 762 |
763 // Whether the RenderFrameHost changed between the start and the commit of | |
764 // the navigation. | |
765 bool switched_rfh = false; | |
766 | |
765 bool notify_webui_of_rv_creation = false; | 767 bool notify_webui_of_rv_creation = false; |
766 | 768 |
767 // Reuse the current RenderFrameHost if its SiteInstance matches the | 769 // Reuse the current RenderFrameHost if its SiteInstance matches the |
768 // navigation's. | 770 // navigation's. |
769 bool no_renderer_swap = current_site_instance == dest_site_instance.get(); | 771 bool no_renderer_swap = current_site_instance == dest_site_instance.get(); |
770 | 772 |
771 if (frame_tree_node_->IsMainFrame()) { | 773 if (frame_tree_node_->IsMainFrame()) { |
772 // Renderer-initiated main frame navigations that may require a | 774 // Renderer-initiated main frame navigations that may require a |
773 // SiteInstance swap are sent to the browser via the OpenURL IPC and are | 775 // SiteInstance swap are sent to the browser via the OpenURL IPC and are |
774 // afterwards treated as browser-initiated navigations. NavigationRequests | 776 // afterwards treated as browser-initiated navigations. NavigationRequests |
775 // marked as renderer-initiated are created by receiving a BeginNavigation | 777 // marked as renderer-initiated are created by receiving a BeginNavigation |
776 // IPC, and will then proceed in the same renderer. In site-per-process | 778 // IPC, and will then proceed in the same renderer. In site-per-process |
777 // mode, it is possible for renderer-intiated navigations to be allowed to | 779 // mode, it is possible for renderer-intiated navigations to be allowed to |
778 // go cross-process. Check it first. | 780 // go cross-process. Check it first. |
779 bool can_renderer_initiate_transfer = | 781 bool can_renderer_initiate_transfer = |
780 render_frame_host_->IsRenderFrameLive() && | 782 render_frame_host_->IsRenderFrameLive() && |
781 ShouldMakeNetworkRequestForURL(request.common_params().url) && | 783 ShouldMakeNetworkRequestForURL(request->common_params().url) && |
782 IsRendererTransferNeededForNavigation(render_frame_host_.get(), | 784 IsRendererTransferNeededForNavigation(render_frame_host_.get(), |
783 request.common_params().url); | 785 request->common_params().url); |
784 | 786 |
785 no_renderer_swap |= | 787 no_renderer_swap |= |
786 !request.browser_initiated() && !can_renderer_initiate_transfer; | 788 !request->browser_initiated() && !can_renderer_initiate_transfer; |
787 } else { | 789 } else { |
788 // Subframe navigations will use the current renderer, unless specifically | 790 // Subframe navigations will use the current renderer, unless specifically |
789 // allowed to swap processes. | 791 // allowed to swap processes. |
790 no_renderer_swap |= !CanSubframeSwapProcess(request.common_params().url, | 792 no_renderer_swap |= !CanSubframeSwapProcess(request->common_params().url, |
791 request.source_site_instance(), | 793 request->source_site_instance(), |
792 request.dest_site_instance()); | 794 request->dest_site_instance()); |
793 } | 795 } |
794 | 796 |
795 if (no_renderer_swap) { | 797 if (no_renderer_swap) { |
796 // GetFrameHostForNavigation will be called more than once during a | 798 // GetFrameHostForNavigation will be called more than once during a |
797 // navigation (currently twice, on request and when it's about to commit in | 799 // navigation (currently twice, on request and when it's about to commit in |
798 // the renderer). In the follow up calls an existing pending WebUI should | 800 // the renderer). In the follow up calls an existing pending WebUI should |
799 // not be recreated if the URL didn't change. So instead of calling | 801 // not be recreated if the URL didn't change. So instead of calling |
800 // CleanUpNavigation just discard the speculative RenderFrameHost if one | 802 // CleanUpNavigation just discard the speculative RenderFrameHost if one |
801 // exists. | 803 // exists. |
802 if (speculative_render_frame_host_) | 804 if (speculative_render_frame_host_) { |
803 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 805 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
804 | 806 |
805 UpdatePendingWebUIOnCurrentFrameHost(request.common_params().url, | 807 if (is_commit) |
806 request.bindings()); | 808 switched_rfh = true; |
809 } | |
810 | |
811 UpdatePendingWebUIOnCurrentFrameHost(request->common_params().url, | |
812 request->bindings()); | |
807 | 813 |
808 navigation_rfh = render_frame_host_.get(); | 814 navigation_rfh = render_frame_host_.get(); |
809 | 815 |
810 DCHECK(!speculative_render_frame_host_); | 816 DCHECK(!speculative_render_frame_host_); |
811 } else { | 817 } else { |
812 // If the current RenderFrameHost cannot be used a speculative one is | 818 // If the current RenderFrameHost cannot be used a speculative one is |
813 // created with the SiteInstance for the current URL. If a speculative | 819 // created with the SiteInstance for the current URL. If a speculative |
814 // RenderFrameHost already exists we try as much as possible to reuse it and | 820 // RenderFrameHost already exists we try as much as possible to reuse it and |
815 // its associated WebUI. | 821 // its associated WebUI. |
816 | 822 |
817 // Check if an existing speculative RenderFrameHost can be reused. | 823 // Check if an existing speculative RenderFrameHost can be reused. |
818 if (!speculative_render_frame_host_ || | 824 if (!speculative_render_frame_host_ || |
819 speculative_render_frame_host_->GetSiteInstance() != | 825 speculative_render_frame_host_->GetSiteInstance() != |
820 dest_site_instance.get()) { | 826 dest_site_instance.get()) { |
821 // If a previous speculative RenderFrameHost didn't exist or if its | 827 // If a previous speculative RenderFrameHost didn't exist or if its |
822 // SiteInstance differs from the one for the current URL, a new one needs | 828 // SiteInstance differs from the one for the current URL, a new one needs |
823 // to be created. | 829 // to be created. |
824 CleanUpNavigation(); | 830 CleanUpNavigation(); |
825 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, | 831 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
826 dest_site_instance.get()); | 832 dest_site_instance.get()); |
827 DCHECK(success); | 833 DCHECK(success); |
834 | |
835 if (is_commit) | |
836 switched_rfh = true; | |
828 } | 837 } |
829 DCHECK(speculative_render_frame_host_); | 838 DCHECK(speculative_render_frame_host_); |
830 | 839 |
831 bool changed_web_ui = speculative_render_frame_host_->UpdatePendingWebUI( | 840 bool changed_web_ui = speculative_render_frame_host_->UpdatePendingWebUI( |
832 request.common_params().url, request.bindings()); | 841 request->common_params().url, request->bindings()); |
833 speculative_render_frame_host_->CommitPendingWebUI(); | 842 speculative_render_frame_host_->CommitPendingWebUI(); |
834 DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui()); | 843 DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui()); |
835 notify_webui_of_rv_creation = | 844 notify_webui_of_rv_creation = |
836 changed_web_ui && speculative_render_frame_host_->web_ui(); | 845 changed_web_ui && speculative_render_frame_host_->web_ui(); |
837 | 846 |
838 navigation_rfh = speculative_render_frame_host_.get(); | 847 navigation_rfh = speculative_render_frame_host_.get(); |
839 | 848 |
840 // Check if our current RFH is live. | 849 // Check if our current RFH is live. |
841 if (!render_frame_host_->IsRenderFrameLive()) { | 850 if (!render_frame_host_->IsRenderFrameLive()) { |
842 // The current RFH is not live. There's no reason to sit around with a | 851 // The current RFH is not live. There's no reason to sit around with a |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
881 } | 890 } |
882 DCHECK(navigation_rfh->IsRenderFrameLive()); | 891 DCHECK(navigation_rfh->IsRenderFrameLive()); |
883 } | 892 } |
884 | 893 |
885 // If a WebUI was created in a speculative RenderFrameHost or a new RenderView | 894 // If a WebUI was created in a speculative RenderFrameHost or a new RenderView |
886 // was created then the WebUI never interacted with the RenderView. Notify | 895 // was created then the WebUI never interacted with the RenderView. Notify |
887 // using RenderViewCreated. | 896 // using RenderViewCreated. |
888 if (notify_webui_of_rv_creation && GetNavigatingWebUI()) | 897 if (notify_webui_of_rv_creation && GetNavigatingWebUI()) |
889 GetNavigatingWebUI()->RenderViewCreated(navigation_rfh->render_view_host()); | 898 GetNavigatingWebUI()->RenderViewCreated(navigation_rfh->render_view_host()); |
890 | 899 |
900 // Update the type of SiteInstance in the NavigationRequest. | |
901 request->set_associated_site_instance_type( | |
902 navigation_rfh == render_frame_host_.get() | |
903 ? NavigationRequest::AssociatedSiteInstanceType::CURRENT | |
904 : NavigationRequest::AssociatedSiteInstanceType::SPECULATIVE); | |
905 | |
906 // If the SiteInstance changed between the start and the end of the | |
907 // navigation, do not send POST data. This avoids POST data from one | |
908 // SiteInstance to be sent to a renderer of another SiteInstance when the | |
909 // navigation encountered a cross-site redirect. | |
Charlie Reis
2016/05/11 00:00:23
See my other comment on ResetPostData. Based on w
clamy
2016/05/11 08:54:41
Done. We indeed don't need to do this.
| |
910 if (switched_rfh) { | |
911 DCHECK(is_commit); | |
912 request->ResetPostData(); | |
913 } | |
914 | |
891 return navigation_rfh; | 915 return navigation_rfh; |
892 } | 916 } |
893 | 917 |
894 // PlzNavigate | 918 // PlzNavigate |
895 void RenderFrameHostManager::CleanUpNavigation() { | 919 void RenderFrameHostManager::CleanUpNavigation() { |
896 CHECK(IsBrowserSideNavigationEnabled()); | 920 CHECK(IsBrowserSideNavigationEnabled()); |
897 if (speculative_render_frame_host_) { | 921 if (speculative_render_frame_host_) { |
898 bool was_loading = speculative_render_frame_host_->is_loading(); | 922 bool was_loading = speculative_render_frame_host_->is_loading(); |
899 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 923 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
900 if (was_loading) | 924 if (was_loading) |
(...skipping 1646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2547 resolved_url)) { | 2571 resolved_url)) { |
2548 DCHECK(!dest_instance || | 2572 DCHECK(!dest_instance || |
2549 dest_instance == render_frame_host_->GetSiteInstance()); | 2573 dest_instance == render_frame_host_->GetSiteInstance()); |
2550 return false; | 2574 return false; |
2551 } | 2575 } |
2552 | 2576 |
2553 return true; | 2577 return true; |
2554 } | 2578 } |
2555 | 2579 |
2556 } // namespace content | 2580 } // namespace content |
OLD | NEW |