| 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 <string> | 10 #include <string> |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation( | 714 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation( |
| 715 request.common_params().url, request.source_site_instance(), | 715 request.common_params().url, request.source_site_instance(), |
| 716 request.dest_site_instance(), candidate_site_instance, | 716 request.dest_site_instance(), candidate_site_instance, |
| 717 request.common_params().transition, | 717 request.common_params().transition, |
| 718 request.restore_type() != RestoreType::NONE, request.is_view_source(), | 718 request.restore_type() != RestoreType::NONE, request.is_view_source(), |
| 719 was_server_redirect); | 719 was_server_redirect); |
| 720 | 720 |
| 721 // The appropriate RenderFrameHost to commit the navigation. | 721 // The appropriate RenderFrameHost to commit the navigation. |
| 722 RenderFrameHostImpl* navigation_rfh = nullptr; | 722 RenderFrameHostImpl* navigation_rfh = nullptr; |
| 723 | 723 |
| 724 bool notify_webui_of_rf_creation = false; | |
| 725 | |
| 726 // Reuse the current RenderFrameHost if its SiteInstance matches the | 724 // Reuse the current RenderFrameHost if its SiteInstance matches the |
| 727 // navigation's. | 725 // navigation's. |
| 728 bool no_renderer_swap = current_site_instance == dest_site_instance.get(); | 726 bool no_renderer_swap = current_site_instance == dest_site_instance.get(); |
| 729 | 727 |
| 730 if (frame_tree_node_->IsMainFrame()) { | 728 if (frame_tree_node_->IsMainFrame()) { |
| 731 // Renderer-initiated main frame navigations that may require a | 729 // Renderer-initiated main frame navigations that may require a |
| 732 // SiteInstance swap are sent to the browser via the OpenURL IPC and are | 730 // SiteInstance swap are sent to the browser via the OpenURL IPC and are |
| 733 // afterwards treated as browser-initiated navigations. NavigationRequests | 731 // afterwards treated as browser-initiated navigations. NavigationRequests |
| 734 // marked as renderer-initiated are created by receiving a BeginNavigation | 732 // marked as renderer-initiated are created by receiving a BeginNavigation |
| 735 // IPC, and will then proceed in the same renderer. In site-per-process | 733 // IPC, and will then proceed in the same renderer. In site-per-process |
| 736 // mode, it is possible for renderer-intiated navigations to be allowed to | 734 // mode, it is possible for renderer-intiated navigations to be allowed to |
| 737 // go cross-process. Check it first. | 735 // go cross-process. Check it first. |
| 738 bool can_renderer_initiate_transfer = | 736 bool can_renderer_initiate_transfer = |
| 739 render_frame_host_->IsRenderFrameLive() && | 737 render_frame_host_->IsRenderFrameLive() && |
| 740 ShouldMakeNetworkRequestForURL(request.common_params().url) && | 738 ShouldMakeNetworkRequestForURL(request.common_params().url) && |
| 741 IsRendererTransferNeededForNavigation(render_frame_host_.get(), | 739 IsRendererTransferNeededForNavigation(render_frame_host_.get(), |
| 742 request.common_params().url); | 740 request.common_params().url); |
| 743 | 741 |
| 744 no_renderer_swap |= | 742 no_renderer_swap |= |
| 745 !request.may_transfer() && !can_renderer_initiate_transfer; | 743 !request.may_transfer() && !can_renderer_initiate_transfer; |
| 746 } else { | 744 } else { |
| 747 // Subframe navigations will use the current renderer, unless specifically | 745 // Subframe navigations will use the current renderer, unless specifically |
| 748 // allowed to swap processes. | 746 // allowed to swap processes. |
| 749 no_renderer_swap |= !CanSubframeSwapProcess( | 747 no_renderer_swap |= !CanSubframeSwapProcess( |
| 750 request.common_params().url, request.source_site_instance(), | 748 request.common_params().url, request.source_site_instance(), |
| 751 request.dest_site_instance(), was_server_redirect); | 749 request.dest_site_instance(), was_server_redirect); |
| 752 } | 750 } |
| 753 | 751 |
| 752 bool notify_webui_of_rf_creation = false; |
| 754 if (no_renderer_swap) { | 753 if (no_renderer_swap) { |
| 755 // GetFrameHostForNavigation will be called more than once during a | 754 // GetFrameHostForNavigation will be called more than once during a |
| 756 // navigation (currently twice, on request and when it's about to commit in | 755 // navigation (currently twice, on request and when it's about to commit in |
| 757 // the renderer). In the follow up calls an existing pending WebUI should | 756 // the renderer). In the follow up calls an existing pending WebUI should |
| 758 // not be recreated if the URL didn't change. So instead of calling | 757 // not be recreated if the URL didn't change. So instead of calling |
| 759 // CleanUpNavigation just discard the speculative RenderFrameHost if one | 758 // CleanUpNavigation just discard the speculative RenderFrameHost if one |
| 760 // exists. | 759 // exists. |
| 761 if (speculative_render_frame_host_) | 760 if (speculative_render_frame_host_) |
| 762 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 761 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
| 763 | 762 |
| 764 UpdatePendingWebUIOnCurrentFrameHost(request.common_params().url, | 763 // Short-term solution: avoid creating a WebUI for subframes because |
| 765 request.bindings()); | 764 // non-PlzNavigate code path doesn't do it and some WebUI pages don't |
| 765 // support it. |
| 766 // TODO(crbug.com/713313): Make WebUI objects always be per-frame instead. |
| 767 if (frame_tree_node_->IsMainFrame()) { |
| 768 UpdatePendingWebUIOnCurrentFrameHost(request.common_params().url, |
| 769 request.bindings()); |
| 770 } |
| 766 | 771 |
| 767 navigation_rfh = render_frame_host_.get(); | 772 navigation_rfh = render_frame_host_.get(); |
| 768 | 773 |
| 769 DCHECK(!speculative_render_frame_host_); | 774 DCHECK(!speculative_render_frame_host_); |
| 770 } else { | 775 } else { |
| 771 // If the current RenderFrameHost cannot be used a speculative one is | 776 // If the current RenderFrameHost cannot be used a speculative one is |
| 772 // created with the SiteInstance for the current URL. If a speculative | 777 // created with the SiteInstance for the current URL. If a speculative |
| 773 // RenderFrameHost already exists we try as much as possible to reuse it and | 778 // RenderFrameHost already exists we try as much as possible to reuse it and |
| 774 // its associated WebUI. | 779 // its associated WebUI. |
| 775 | 780 |
| 776 // Check if an existing speculative RenderFrameHost can be reused. | 781 // Check if an existing speculative RenderFrameHost can be reused. |
| 777 if (!speculative_render_frame_host_ || | 782 if (!speculative_render_frame_host_ || |
| 778 speculative_render_frame_host_->GetSiteInstance() != | 783 speculative_render_frame_host_->GetSiteInstance() != |
| 779 dest_site_instance.get()) { | 784 dest_site_instance.get()) { |
| 780 // If a previous speculative RenderFrameHost didn't exist or if its | 785 // If a previous speculative RenderFrameHost didn't exist or if its |
| 781 // SiteInstance differs from the one for the current URL, a new one needs | 786 // SiteInstance differs from the one for the current URL, a new one needs |
| 782 // to be created. | 787 // to be created. |
| 783 CleanUpNavigation(); | 788 CleanUpNavigation(); |
| 784 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, | 789 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
| 785 dest_site_instance.get()); | 790 dest_site_instance.get()); |
| 786 DCHECK(success); | 791 DCHECK(success); |
| 787 } | 792 } |
| 788 DCHECK(speculative_render_frame_host_); | 793 DCHECK(speculative_render_frame_host_); |
| 789 | 794 |
| 790 bool changed_web_ui = speculative_render_frame_host_->UpdatePendingWebUI( | 795 // Short-term solution: avoid creating a WebUI for subframes because |
| 791 request.common_params().url, request.bindings()); | 796 // non-PlzNavigate code path doesn't do it and some WebUI pages don't |
| 792 speculative_render_frame_host_->CommitPendingWebUI(); | 797 // support it. |
| 793 DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui()); | 798 // TODO(crbug.com/713313): Make WebUI objects always be per-frame instead. |
| 794 notify_webui_of_rf_creation = | 799 if (frame_tree_node_->IsMainFrame()) { |
| 795 changed_web_ui && speculative_render_frame_host_->web_ui(); | 800 bool changed_web_ui = speculative_render_frame_host_->UpdatePendingWebUI( |
| 796 | 801 request.common_params().url, request.bindings()); |
| 802 speculative_render_frame_host_->CommitPendingWebUI(); |
| 803 DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui()); |
| 804 notify_webui_of_rf_creation = |
| 805 changed_web_ui && speculative_render_frame_host_->web_ui(); |
| 806 } |
| 797 navigation_rfh = speculative_render_frame_host_.get(); | 807 navigation_rfh = speculative_render_frame_host_.get(); |
| 798 | 808 |
| 799 // Check if our current RFH is live. | 809 // Check if our current RFH is live. |
| 800 if (!render_frame_host_->IsRenderFrameLive()) { | 810 if (!render_frame_host_->IsRenderFrameLive()) { |
| 801 // The current RFH is not live. There's no reason to sit around with a | 811 // The current RFH is not live. There's no reason to sit around with a |
| 802 // sad tab or a newly created RFH while we wait for the navigation to | 812 // sad tab or a newly created RFH while we wait for the navigation to |
| 803 // complete. Just switch to the speculative RFH now and go back to normal. | 813 // complete. Just switch to the speculative RFH now and go back to normal. |
| 804 // (Note that we don't care about on{before}unload handlers if the current | 814 // (Note that we don't care about on{before}unload handlers if the current |
| 805 // RFH isn't live.) | 815 // RFH isn't live.) |
| 806 // | 816 // |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 // removed once the process manager moves away from NotificationService. | 857 // removed once the process manager moves away from NotificationService. |
| 848 // See https://crbug.com/462682. | 858 // See https://crbug.com/462682. |
| 849 delegate_->NotifyMainFrameSwappedFromRenderManager( | 859 delegate_->NotifyMainFrameSwappedFromRenderManager( |
| 850 nullptr, render_frame_host_->render_view_host()); | 860 nullptr, render_frame_host_->render_view_host()); |
| 851 } | 861 } |
| 852 } | 862 } |
| 853 | 863 |
| 854 // If a WebUI was created in a speculative RenderFrameHost or a new | 864 // If a WebUI was created in a speculative RenderFrameHost or a new |
| 855 // RenderFrame was created then the WebUI never interacted with the | 865 // RenderFrame was created then the WebUI never interacted with the |
| 856 // RenderFrame or its RenderView. Notify using RenderFrameCreated. | 866 // RenderFrame or its RenderView. Notify using RenderFrameCreated. |
| 857 if (notify_webui_of_rf_creation && GetNavigatingWebUI()) | 867 // |
| 868 // Short-term solution: avoid creating a WebUI for subframes because |
| 869 // non-PlzNavigate code path doesn't do it and some WebUI pages don't |
| 870 // support it. |
| 871 // TODO(crbug.com/713313): Make WebUI objects always be per-frame instead. |
| 872 if (notify_webui_of_rf_creation && GetNavigatingWebUI() && |
| 873 frame_tree_node_->IsMainFrame()) { |
| 858 GetNavigatingWebUI()->RenderFrameCreated(navigation_rfh); | 874 GetNavigatingWebUI()->RenderFrameCreated(navigation_rfh); |
| 875 } |
| 859 | 876 |
| 860 return navigation_rfh; | 877 return navigation_rfh; |
| 861 } | 878 } |
| 862 | 879 |
| 863 // PlzNavigate | 880 // PlzNavigate |
| 864 void RenderFrameHostManager::CleanUpNavigation() { | 881 void RenderFrameHostManager::CleanUpNavigation() { |
| 865 CHECK(IsBrowserSideNavigationEnabled()); | 882 CHECK(IsBrowserSideNavigationEnabled()); |
| 866 if (speculative_render_frame_host_) { | 883 if (speculative_render_frame_host_) { |
| 867 bool was_loading = speculative_render_frame_host_->is_loading(); | 884 bool was_loading = speculative_render_frame_host_->is_loading(); |
| 868 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 885 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
| (...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 delegate_->IsHidden()) { | 2854 delegate_->IsHidden()) { |
| 2838 if (delegate_->IsHidden()) { | 2855 if (delegate_->IsHidden()) { |
| 2839 render_frame_host_->GetView()->Hide(); | 2856 render_frame_host_->GetView()->Hide(); |
| 2840 } else { | 2857 } else { |
| 2841 render_frame_host_->GetView()->Show(); | 2858 render_frame_host_->GetView()->Show(); |
| 2842 } | 2859 } |
| 2843 } | 2860 } |
| 2844 } | 2861 } |
| 2845 | 2862 |
| 2846 } // namespace content | 2863 } // namespace content |
| OLD | NEW |