Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: content/browser/frame_host/navigator_impl.cc

Issue 872473003: PlzNavigate: Remove the RequestNavigation IPC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/navigator_impl.h" 5 #include "content/browser/frame_host/navigator_impl.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/time/time.h" 9 #include "base/time/time.h"
10 #include "content/browser/frame_host/frame_tree.h" 10 #include "content/browser/frame_host/frame_tree.h"
11 #include "content/browser/frame_host/frame_tree_node.h" 11 #include "content/browser/frame_host/frame_tree_node.h"
12 #include "content/browser/frame_host/navigation_controller_impl.h" 12 #include "content/browser/frame_host/navigation_controller_impl.h"
13 #include "content/browser/frame_host/navigation_entry_impl.h" 13 #include "content/browser/frame_host/navigation_entry_impl.h"
14 #include "content/browser/frame_host/navigation_request.h" 14 #include "content/browser/frame_host/navigation_request.h"
15 #include "content/browser/frame_host/navigation_request_info.h" 15 #include "content/browser/frame_host/navigation_request_info.h"
16 #include "content/browser/frame_host/navigator_delegate.h" 16 #include "content/browser/frame_host/navigator_delegate.h"
17 #include "content/browser/frame_host/render_frame_host_impl.h" 17 #include "content/browser/frame_host/render_frame_host_impl.h"
18 #include "content/browser/renderer_host/render_view_host_impl.h" 18 #include "content/browser/renderer_host/render_view_host_impl.h"
19 #include "content/browser/site_instance_impl.h" 19 #include "content/browser/site_instance_impl.h"
20 #include "content/browser/webui/web_ui_controller_factory_registry.h" 20 #include "content/browser/webui/web_ui_controller_factory_registry.h"
21 #include "content/browser/webui/web_ui_impl.h" 21 #include "content/browser/webui/web_ui_impl.h"
22 #include "content/common/frame_messages.h"
22 #include "content/common/navigation_params.h" 23 #include "content/common/navigation_params.h"
23 #include "content/common/view_messages.h" 24 #include "content/common/view_messages.h"
24 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/content_browser_client.h" 26 #include "content/public/browser/content_browser_client.h"
26 #include "content/public/browser/global_request_id.h" 27 #include "content/public/browser/global_request_id.h"
27 #include "content/public/browser/invalidate_type.h" 28 #include "content/public/browser/invalidate_type.h"
28 #include "content/public/browser/navigation_controller.h" 29 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/navigation_details.h" 30 #include "content/public/browser/navigation_details.h"
30 #include "content/public/browser/page_navigator.h" 31 #include "content/public/browser/page_navigator.h"
31 #include "content/public/browser/render_view_host.h" 32 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/stream_handle.h" 33 #include "content/public/browser/stream_handle.h"
33 #include "content/public/browser/user_metrics.h" 34 #include "content/public/browser/user_metrics.h"
34 #include "content/public/common/bindings_policy.h" 35 #include "content/public/common/bindings_policy.h"
35 #include "content/public/common/content_client.h" 36 #include "content/public/common/content_client.h"
36 #include "content/public/common/content_switches.h" 37 #include "content/public/common/content_switches.h"
37 #include "content/public/common/resource_response.h" 38 #include "content/public/common/resource_response.h"
38 #include "content/public/common/url_constants.h" 39 #include "content/public/common/url_constants.h"
39 #include "content/public/common/url_utils.h" 40 #include "content/public/common/url_utils.h"
40 #include "net/base/load_flags.h"
41 #include "net/http/http_request_headers.h"
42 41
43 namespace content { 42 namespace content {
44 43
45 namespace { 44 namespace {
46 45
47 FrameMsg_Navigate_Type::Value GetNavigationType( 46 FrameMsg_Navigate_Type::Value GetNavigationType(
48 BrowserContext* browser_context, const NavigationEntryImpl& entry, 47 BrowserContext* browser_context, const NavigationEntryImpl& entry,
49 NavigationController::ReloadType reload_type) { 48 NavigationController::ReloadType reload_type) {
50 switch (reload_type) { 49 switch (reload_type) {
51 case NavigationControllerImpl::RELOAD: 50 case NavigationControllerImpl::RELOAD:
(...skipping 11 matching lines...) Expand all
63 if (entry.restore_type() == 62 if (entry.restore_type() ==
64 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) { 63 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) {
65 if (entry.GetHasPostData()) 64 if (entry.GetHasPostData())
66 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; 65 return FrameMsg_Navigate_Type::RESTORE_WITH_POST;
67 return FrameMsg_Navigate_Type::RESTORE; 66 return FrameMsg_Navigate_Type::RESTORE;
68 } 67 }
69 68
70 return FrameMsg_Navigate_Type::NORMAL; 69 return FrameMsg_Navigate_Type::NORMAL;
71 } 70 }
72 71
73 // PlzNavigate
74 // Returns the net load flags to use based on the navigation type.
75 // TODO(clamy): unify the code with what is happening on the renderer side.
76 int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) {
77 int load_flags = net::LOAD_NORMAL;
78 switch (navigation_type) {
79 case FrameMsg_Navigate_Type::RELOAD:
80 case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
81 load_flags |= net::LOAD_VALIDATE_CACHE;
82 break;
83 case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE:
84 load_flags |= net::LOAD_BYPASS_CACHE;
85 break;
86 case FrameMsg_Navigate_Type::RESTORE:
87 load_flags |= net::LOAD_PREFERRING_CACHE;
88 break;
89 case FrameMsg_Navigate_Type::RESTORE_WITH_POST:
90 load_flags |= net::LOAD_ONLY_FROM_CACHE;
91 break;
92 case FrameMsg_Navigate_Type::NORMAL:
93 default:
94 break;
95 }
96 return load_flags;
97 }
98
99 // PlzNavigate
100 // Generates a default FrameHostMsg_BeginNavigation_Params to be used when there
101 // is no live renderer.
102 FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation(
103 const RequestNavigationParams& request_params,
104 FrameMsg_Navigate_Type::Value navigation_type) {
105 FrameHostMsg_BeginNavigation_Params begin_navigation_params;
106 begin_navigation_params.method = request_params.is_post ? "POST" : "GET";
107 begin_navigation_params.load_flags =
108 LoadFlagFromNavigationType(navigation_type);
109
110 // Copy existing headers and add necessary headers that may not be present
111 // in the RequestNavigationParams.
112 net::HttpRequestHeaders headers;
113 headers.AddHeadersFromString(request_params.extra_headers);
114 headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
115 GetContentClient()->GetUserAgent());
116 headers.SetHeaderIfMissing("Accept", "*/*");
117 begin_navigation_params.headers = headers.ToString();
118
119 // Fill POST data from the browser in the request body.
120 if (request_params.is_post) {
121 begin_navigation_params.request_body = new ResourceRequestBody();
122 begin_navigation_params.request_body->AppendBytes(
123 reinterpret_cast<const char *>(
124 &request_params.browser_initiated_post_data.front()),
125 request_params.browser_initiated_post_data.size());
126 }
127
128 begin_navigation_params.has_user_gesture = false;
129 return begin_navigation_params;
130 }
131
132 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { 72 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) {
133 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 73 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
134 switches::kSitePerProcess)) 74 switches::kSitePerProcess))
135 return rfh->frame_tree_node()->render_manager(); 75 return rfh->frame_tree_node()->render_manager();
136 76
137 return rfh->frame_tree_node()->frame_tree()->root()->render_manager(); 77 return rfh->frame_tree_node()->frame_tree()->root()->render_manager();
138 } 78 }
139 79
140 void MakeNavigateParams(const NavigationEntryImpl& entry, 80 void MakeNavigateParams(const NavigationEntryImpl& entry,
141 NavigationControllerImpl* controller, 81 NavigationControllerImpl* controller,
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 679
740 // Navigations in Web UI pages count as browser-initiated navigations. 680 // Navigations in Web UI pages count as browser-initiated navigations.
741 params.is_renderer_initiated = false; 681 params.is_renderer_initiated = false;
742 } 682 }
743 683
744 if (delegate_) 684 if (delegate_)
745 delegate_->RequestOpenURL(render_frame_host, params); 685 delegate_->RequestOpenURL(render_frame_host, params);
746 } 686 }
747 687
748 // PlzNavigate 688 // PlzNavigate
749 void NavigatorImpl::OnBeginNavigation( 689 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
750 FrameTreeNode* frame_tree_node, 690 bool proceed) {
751 const FrameHostMsg_BeginNavigation_Params& params,
752 const CommonNavigationParams& common_params) {
753 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 691 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
754 switches::kEnableBrowserSideNavigation)); 692 switches::kEnableBrowserSideNavigation));
755 DCHECK(frame_tree_node); 693 DCHECK(frame_tree_node);
756 694
757 NavigationRequest* navigation_request = 695 NavigationRequest* navigation_request =
758 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); 696 navigation_request_map_.get(frame_tree_node->frame_tree_node_id());
759 697
760 if (!navigation_request) { 698 // The NavigationRequest may have been canceled while the renderer was
761 // This is a renderer initiated navigation, so generate a new 699 // executing the BeforeUnload event.
762 // NavigationRequest and store it in the map. 700 if (!navigation_request)
763 // TODO(clamy): Check if some PageState should be provided here. 701 return;
764 // TODO(clamy): See how we should handle override of the user agent when the
765 // navigation may start in a renderer and commit in another one.
766 // TODO(clamy): See if the navigation start time should be measured in the
767 // renderer and sent to the browser instead of being measured here.
768 scoped_ptr<NavigationRequest> scoped_request(new NavigationRequest(
769 frame_tree_node, common_params,
770 CommitNavigationParams(PageState(), false, base::TimeTicks::Now()),
771 nullptr));
772 navigation_request = scoped_request.get();
773 navigation_request_map_.set(
774 frame_tree_node->frame_tree_node_id(), scoped_request.Pass());
775 }
776 DCHECK(navigation_request);
777 702
778 // Update the referrer with the one received from the renderer. 703 DCHECK(navigation_request->state() ==
779 navigation_request->common_params().referrer = common_params.referrer; 704 NavigationRequest::WAITING_FOR_RENDERER_RESPONSE);
davidben 2015/02/03 02:23:21 Nit: DCHECK_EQ
carlosk 2015/02/03 16:06:02 Isn't it possible that the original request was ca
clamy 2015/02/03 16:17:09 Yes but in that case we do not send another Before
clamy 2015/02/03 16:17:09 Done.
780 705
781 scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params)); 706 if (proceed)
782 707 BeginNavigation(frame_tree_node);
783 info->first_party_for_cookies = 708 else
784 frame_tree_node->IsMainFrame() 709 CancelNavigation(frame_tree_node);
785 ? navigation_request->common_params().url
786 : frame_tree_node->frame_tree()->root()->current_url();
787 info->is_main_frame = frame_tree_node->IsMainFrame();
788 info->parent_is_main_frame = !frame_tree_node->parent() ?
789 false : frame_tree_node->parent()->IsMainFrame();
790
791 // First start the request on the IO thread.
792 navigation_request->BeginNavigation(info.Pass(), params.request_body);
793
794 // Then notify the RenderFrameHostManager so it can speculatively create a
795 // RenderFrameHost (and potentially a new renderer process) in parallel.
796 frame_tree_node->render_manager()->BeginNavigation(*navigation_request);
797 } 710 }
798 711
799 // PlzNavigate 712 // PlzNavigate
713 void NavigatorImpl::OnBeginNavigation(
714 FrameTreeNode* frame_tree_node,
715 const CommonNavigationParams& common_params,
716 const BeginNavigationParams& begin_params,
717 scoped_refptr<ResourceRequestBody> body) {
718 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
719 switches::kEnableBrowserSideNavigation));
720 DCHECK(frame_tree_node);
721
722 // This is a renderer initiated navigation, so generate a new
nasko 2015/02/02 21:17:43 nit: renderer-initiated
clamy 2015/02/03 16:17:09 Done.
723 // NavigationRequest and store it in the map.
724 // TODO(clamy): Renderer-initiated navigations should not always cancel the
725 // current one.
726 scoped_ptr<NavigationRequest> navigation_request =
727 NavigationRequest::CreateRendererInitiated(
728 frame_tree_node, common_params, begin_params, body);
729 navigation_request_map_.set(
carlosk 2015/02/03 16:06:02 Don't we need to verify first if another request i
clamy 2015/02/03 16:17:09 That's the TODO above this block of code. The patc
730 frame_tree_node->frame_tree_node_id(), navigation_request.Pass());
731
732 BeginNavigation(frame_tree_node);
733 }
734
735 // PlzNavigate
800 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, 736 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node,
801 ResourceResponse* response, 737 ResourceResponse* response,
802 scoped_ptr<StreamHandle> body) { 738 scoped_ptr<StreamHandle> body) {
803 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 739 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
804 switches::kEnableBrowserSideNavigation)); 740 switches::kEnableBrowserSideNavigation));
805 741
806 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not 742 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not
807 // commit; they leave the frame showing the previous page. 743 // commit; they leave the frame showing the previous page.
808 if (response->head.headers.get() && 744 if (response->head.headers.get() &&
809 (response->head.headers->response_code() == 204 || 745 (response->head.headers->response_code() == 204 ||
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 FrameTreeNode* frame_tree_node, 834 FrameTreeNode* frame_tree_node,
899 const NavigationEntryImpl& entry, 835 const NavigationEntryImpl& entry,
900 NavigationController::ReloadType reload_type, 836 NavigationController::ReloadType reload_type,
901 base::TimeTicks navigation_start) { 837 base::TimeTicks navigation_start) {
902 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 838 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
903 switches::kEnableBrowserSideNavigation)); 839 switches::kEnableBrowserSideNavigation));
904 DCHECK(frame_tree_node); 840 DCHECK(frame_tree_node);
905 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); 841 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id();
906 FrameMsg_Navigate_Type::Value navigation_type = 842 FrameMsg_Navigate_Type::Value navigation_type =
907 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); 843 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type);
908 scoped_ptr<NavigationRequest> navigation_request = NavigationRequest::Create( 844 scoped_ptr<NavigationRequest> navigation_request =
909 frame_tree_node, entry, navigation_type, navigation_start); 845 NavigationRequest::CreateBrowserInitiated(
910 RequestNavigationParams request_params(entry.GetHasPostData(), 846 frame_tree_node, entry, navigation_type, navigation_start);
911 entry.extra_headers(),
912 entry.GetBrowserInitiatedPostData());
913 // TODO(clamy): Check if navigations are blocked and if so store the 847 // TODO(clamy): Check if navigations are blocked and if so store the
914 // parameters. 848 // parameters.
915 849
916 // If there is an ongoing request, replace it. 850 // If there is an ongoing request, replace it.
917 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); 851 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass());
918 852
919 if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) { 853 // Have the current renderer execute its BeforeUnload event if needed. If it
nasko 2015/02/02 21:17:43 nit: beforeUnload
clamy 2015/02/03 16:17:09 Done.
920 NavigationRequest* request_to_send = 854 // is not needed (eg. the renderer is not live), BeginNavigation should get
921 navigation_request_map_.get(frame_tree_node_id); 855 // called.
922 frame_tree_node->current_frame_host()->Send(new FrameMsg_RequestNavigation( 856 NavigationRequest* request_to_send =
923 frame_tree_node->current_frame_host()->GetRoutingID(), 857 navigation_request_map_.get(frame_tree_node_id);
924 request_to_send->common_params(), request_params)); 858 request_to_send->SetWaitingForRendererResponse();
925 request_to_send->SetWaitingForRendererResponse(); 859 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true);
nasko 2015/02/02 21:17:43 Do we know this is a cross-site transition? It cou
davidben 2015/02/03 02:23:21 Even if the navigation is same-site, I think we'll
clamy 2015/02/03 16:17:09 My understanding is that this flag is used by Rend
nasko 2015/02/04 00:14:19 Indeed renaming it makes sense.
clamy 2015/02/05 15:33:13 Included the renaming in this CL.
926 return true; 860 return true;
carlosk 2015/02/03 16:06:02 This return doesn't seem to be meaningful anymore.
clamy 2015/02/03 16:17:09 We either always return true here, or in NavigateT
nasko 2015/02/04 00:14:19 If this method cannot fail, it shouldn't be return
clamy 2015/02/05 15:33:13 It's a simple enough change, so including it in th
927 } 861 }
928 862
929 // The navigation request is sent directly to the IO thread. 863 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) {
930 OnBeginNavigation( 864 NavigationRequest* navigation_request =
931 frame_tree_node, 865 navigation_request_map_.get(frame_tree_node->frame_tree_node_id());
932 MakeDefaultBeginNavigation(request_params, navigation_type), 866
933 navigation_request_map_.get(frame_tree_node_id)->common_params()); 867 // A browser-initiated navigation could have been cancelled while it was
934 return true; 868 // waiting for the BeforeUnload event to execute.
869 if (!navigation_request)
870 return;
871
872 // First start the request on the IO thread.
873 navigation_request->BeginNavigation();
874
875 // Then notify the RenderFrameHostManager so it can speculatively create a
876 // RenderFrameHost (and potentially a new renderer process) in parallel.
877 frame_tree_node->render_manager()->BeginNavigation(*navigation_request);
935 } 878 }
936 879
937 void NavigatorImpl::RecordNavigationMetrics( 880 void NavigatorImpl::RecordNavigationMetrics(
938 const LoadCommittedDetails& details, 881 const LoadCommittedDetails& details,
939 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, 882 const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
940 SiteInstance* site_instance) { 883 SiteInstance* site_instance) {
941 DCHECK(site_instance->HasProcess()); 884 DCHECK(site_instance->HasProcess());
942 885
943 if (!details.is_in_page) 886 if (!details.is_in_page)
944 RecordAction(base::UserMetricsAction("FrameLoad")); 887 RecordAction(base::UserMetricsAction("FrameLoad"));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", 924 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted",
982 time_to_commit); 925 time_to_commit);
983 UMA_HISTOGRAM_TIMES( 926 UMA_HISTOGRAM_TIMES(
984 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", 927 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted",
985 time_to_network); 928 time_to_network);
986 } 929 }
987 navigation_data_.reset(); 930 navigation_data_.reset();
988 } 931 }
989 932
990 } // namespace content 933 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698