Chromium Code Reviews| 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 |