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

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

Issue 2901833002: Create NavigationHandle after beforeunload with PlzNavigate. (Closed)
Patch Set: small fix from jam Created 3 years, 7 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 <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 // We used to cancel the pending renderer here for cross-site downloads. 273 // We used to cancel the pending renderer here for cross-site downloads.
274 // However, it's not safe to do that because the download logic repeatedly 274 // However, it's not safe to do that because the download logic repeatedly
275 // looks for this WebContents based on a render ID. Instead, we just 275 // looks for this WebContents based on a render ID. Instead, we just
276 // leave the pending renderer around until the next navigation event 276 // leave the pending renderer around until the next navigation event
277 // (Navigate, DidNavigate, etc), which will clean it up properly. 277 // (Navigate, DidNavigate, etc), which will clean it up properly.
278 // 278 //
279 // TODO(creis): Find a way to cancel any pending RFH here. 279 // TODO(creis): Find a way to cancel any pending RFH here.
280 } 280 }
281 281
282 // Discard the pending navigation entry if needed. 282 // Discard the pending navigation entry if needed.
283 DiscardPendingEntryIfNeeded(render_frame_host->navigation_handle()); 283 int expected_pending_entry_id =
284 render_frame_host->navigation_handle()
285 ? render_frame_host->navigation_handle()->pending_nav_entry_id()
286 : 0;
287 DiscardPendingEntryIfNeeded(expected_pending_entry_id);
284 } 288 }
285 289
286 void NavigatorImpl::DidFailLoadWithError( 290 void NavigatorImpl::DidFailLoadWithError(
287 RenderFrameHostImpl* render_frame_host, 291 RenderFrameHostImpl* render_frame_host,
288 const GURL& url, 292 const GURL& url,
289 int error_code, 293 int error_code,
290 const base::string16& error_description, 294 const base::string16& error_description,
291 bool was_ignored_by_handler) { 295 bool was_ignored_by_handler) {
292 if (delegate_) { 296 if (delegate_) {
293 delegate_->DidFailLoadWithError( 297 delegate_->DidFailLoadWithError(
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 node->unique_name(), -1, -1, nullptr, 933 node->unique_name(), -1, -1, nullptr,
930 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, 934 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
931 referrer_to_use, method, -1); 935 referrer_to_use, method, -1);
932 } 936 }
933 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, 937 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false,
934 false, false, post_body); 938 false, false, post_body);
935 } 939 }
936 940
937 // PlzNavigate 941 // PlzNavigate
938 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, 942 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
939 bool proceed) { 943 bool proceed,
944 const base::TimeTicks& proceed_time) {
940 CHECK(IsBrowserSideNavigationEnabled()); 945 CHECK(IsBrowserSideNavigationEnabled());
941 DCHECK(frame_tree_node); 946 DCHECK(frame_tree_node);
942 947
943 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); 948 NavigationRequest* navigation_request = frame_tree_node->navigation_request();
944 949
945 // The NavigationRequest may have been canceled while the renderer was 950 // The NavigationRequest may have been canceled while the renderer was
946 // executing the BeforeUnload event. 951 // executing the BeforeUnload event.
947 if (!navigation_request) 952 if (!navigation_request)
948 return; 953 return;
949 954
955 // Update the navigation start: it should be when it was determined that the
956 // navigation will proceed.
957 navigation_request->set_navigation_start_time(proceed_time);
958
950 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, 959 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE,
951 navigation_request->state()); 960 navigation_request->state());
952 961
953 // If the navigation is allowed to proceed, send the request to the IO thread. 962 // If the navigation is allowed to proceed, send the request to the IO thread.
954 if (proceed) 963 if (proceed)
955 navigation_request->BeginNavigation(); 964 navigation_request->BeginNavigation();
956 else 965 else
957 CancelNavigation(frame_tree_node, true); 966 CancelNavigation(frame_tree_node, true);
958 } 967 }
959 968
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 !begin_params.has_user_gesture) { 1000 !begin_params.has_user_gesture) {
992 RenderFrameHost* current_frame_host = 1001 RenderFrameHost* current_frame_host =
993 frame_tree_node->render_manager()->current_frame_host(); 1002 frame_tree_node->render_manager()->current_frame_host();
994 current_frame_host->Send( 1003 current_frame_host->Send(
995 new FrameMsg_Stop(current_frame_host->GetRoutingID())); 1004 new FrameMsg_Stop(current_frame_host->GetRoutingID()));
996 return; 1005 return;
997 } 1006 }
998 1007
999 // In all other cases the current navigation, if any, is canceled and a new 1008 // In all other cases the current navigation, if any, is canceled and a new
1000 // NavigationRequest is created for the node. 1009 // NavigationRequest is created for the node.
1001 frame_tree_node->CreatedNavigationRequest(
1002 NavigationRequest::CreateRendererInitiated(
1003 frame_tree_node, common_params, begin_params,
1004 controller_->GetLastCommittedEntryIndex(),
1005 controller_->GetEntryCount()));
1006 NavigationRequest* navigation_request = frame_tree_node->navigation_request();
1007 if (frame_tree_node->IsMainFrame()) { 1010 if (frame_tree_node->IsMainFrame()) {
1008 // Renderer-initiated main-frame navigations that need to swap processes 1011 // Renderer-initiated main-frame navigations that need to swap processes
1009 // will go to the browser via a OpenURL call, and then be handled by the 1012 // will go to the browser via a OpenURL call, and then be handled by the
1010 // same code path as browser-initiated navigations. For renderer-initiated 1013 // same code path as browser-initiated navigations. For renderer-initiated
1011 // main frame navigation that start via a BeginNavigation IPC, the 1014 // main frame navigation that start via a BeginNavigation IPC, the
1012 // RenderFrameHost will not be swapped. Therefore it is safe to call 1015 // RenderFrameHost will not be swapped. Therefore it is safe to call
1013 // DidStartMainFrameNavigation with the SiteInstance from the current 1016 // DidStartMainFrameNavigation with the SiteInstance from the current
1014 // RenderFrameHost. 1017 // RenderFrameHost.
1015 DidStartMainFrameNavigation( 1018 DidStartMainFrameNavigation(
1016 common_params.url, 1019 common_params.url,
1017 frame_tree_node->current_frame_host()->GetSiteInstance(), nullptr); 1020 frame_tree_node->current_frame_host()->GetSiteInstance(), nullptr);
1018 navigation_data_.reset(); 1021 navigation_data_.reset();
1019 } 1022 }
1023 NavigationEntryImpl* pending_entry = controller_->GetPendingEntry();
1024 frame_tree_node->CreatedNavigationRequest(
1025 NavigationRequest::CreateRendererInitiated(
1026 frame_tree_node, pending_entry, common_params, begin_params,
1027 controller_->GetLastCommittedEntryIndex(),
1028 controller_->GetEntryCount()));
1029 NavigationRequest* navigation_request = frame_tree_node->navigation_request();
1020 1030
1021 // For main frames, NavigationHandle will be created after the call to 1031 // For main frames, NavigationHandle will be created after the call to
1022 // |DidStartMainFrameNavigation|, so it receives the most up to date pending 1032 // |DidStartMainFrameNavigation|, so it receives the most up to date pending
1023 // entry from the NavigationController. 1033 // entry from the NavigationController.
1024 NavigationEntry* pending_entry = controller_->GetPendingEntry();
1025 navigation_request->CreateNavigationHandle(
1026 pending_entry ? pending_entry->GetUniqueID() : 0);
1027 navigation_request->BeginNavigation(); 1034 navigation_request->BeginNavigation();
1028 } 1035 }
1029 1036
1030 void NavigatorImpl::OnAbortNavigation(FrameTreeNode* frame_tree_node) { 1037 void NavigatorImpl::OnAbortNavigation(FrameTreeNode* frame_tree_node) {
1031 NavigationRequest* ongoing_navigation_request = 1038 NavigationRequest* ongoing_navigation_request =
1032 frame_tree_node->navigation_request(); 1039 frame_tree_node->navigation_request();
1033 if (!ongoing_navigation_request || 1040 if (!ongoing_navigation_request ||
1034 ongoing_navigation_request->browser_initiated()) { 1041 ongoing_navigation_request->browser_initiated()) {
1035 return; 1042 return;
1036 } 1043 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 const base::TimeTicks& renderer_before_unload_end_time) { 1076 const base::TimeTicks& renderer_before_unload_end_time) {
1070 // Only stores the beforeunload delay if we're tracking a browser initiated 1077 // Only stores the beforeunload delay if we're tracking a browser initiated
1071 // navigation and it happened later than the navigation request. 1078 // navigation and it happened later than the navigation request.
1072 if (navigation_data_ && 1079 if (navigation_data_ &&
1073 renderer_before_unload_start_time > navigation_data_->start_time_) { 1080 renderer_before_unload_start_time > navigation_data_->start_time_) {
1074 navigation_data_->before_unload_delay_ = 1081 navigation_data_->before_unload_delay_ =
1075 renderer_before_unload_end_time - renderer_before_unload_start_time; 1082 renderer_before_unload_end_time - renderer_before_unload_start_time;
1076 } 1083 }
1077 } 1084 }
1078 1085
1079 void NavigatorImpl::DiscardPendingEntryIfNeeded(NavigationHandleImpl* handle) { 1086 void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id) {
1080 // Racy conditions can cause a fail message to arrive after its corresponding 1087 // Racy conditions can cause a fail message to arrive after its corresponding
1081 // pending entry has been replaced by another navigation. If 1088 // pending entry has been replaced by another navigation. If
1082 // |DiscardPendingEntry| is called in this case, then the completely valid 1089 // |DiscardPendingEntry| is called in this case, then the completely valid
1083 // entry for the new navigation would be discarded. See crbug.com/513742. To 1090 // entry for the new navigation would be discarded. See crbug.com/513742. To
1084 // catch this case, the current pending entry is compared against the current 1091 // catch this case, the current pending entry is compared against the current
1085 // navigation handle's entry id, which should correspond to the failed load. 1092 // navigation handle's entry id, which should correspond to the failed load.
1086 NavigationEntry* pending_entry = controller_->GetPendingEntry(); 1093 NavigationEntry* pending_entry = controller_->GetPendingEntry();
1087 bool pending_matches_fail_msg = 1094 bool pending_matches_fail_msg =
1088 handle && pending_entry && 1095 pending_entry &&
1089 handle->pending_nav_entry_id() == pending_entry->GetUniqueID(); 1096 expected_pending_entry_id == pending_entry->GetUniqueID();
1090 if (!pending_matches_fail_msg) 1097 if (!pending_matches_fail_msg)
1091 return; 1098 return;
1092 1099
1093 // We usually clear the pending entry when it fails, so that an arbitrary URL 1100 // We usually clear the pending entry when it fails, so that an arbitrary URL
1094 // isn't left visible above a committed page. This must be enforced when the 1101 // isn't left visible above a committed page. This must be enforced when the
1095 // pending entry isn't visible (e.g., renderer-initiated navigations) to 1102 // pending entry isn't visible (e.g., renderer-initiated navigations) to
1096 // prevent URL spoofs for same-document navigations that don't go through 1103 // prevent URL spoofs for same-document navigations that don't go through
1097 // DidStartProvisionalLoadForFrame. 1104 // DidStartProvisionalLoadForFrame.
1098 // 1105 //
1099 // However, we do preserve the pending entry in some cases, such as on the 1106 // However, we do preserve the pending entry in some cases, such as on the
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 render_frame_host->CommitNavigation( 1174 render_frame_host->CommitNavigation(
1168 nullptr, // response 1175 nullptr, // response
1169 nullptr, // body 1176 nullptr, // body
1170 mojo::ScopedDataPipeConsumerHandle(), scoped_request->common_params(), 1177 mojo::ScopedDataPipeConsumerHandle(), scoped_request->common_params(),
1171 scoped_request->request_params(), scoped_request->is_view_source()); 1178 scoped_request->request_params(), scoped_request->is_view_source());
1172 return; 1179 return;
1173 } 1180 }
1174 1181
1175 frame_tree_node->CreatedNavigationRequest(std::move(scoped_request)); 1182 frame_tree_node->CreatedNavigationRequest(std::move(scoped_request));
1176 1183
1177 frame_tree_node->navigation_request()->CreateNavigationHandle(
1178 entry.GetUniqueID());
1179
1180 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); 1184 NavigationRequest* navigation_request = frame_tree_node->navigation_request();
1181 if (!navigation_request) 1185 if (!navigation_request)
1182 return; // Navigation was synchronously stopped. 1186 return; // Navigation was synchronously stopped.
1183 1187
1184 navigation_request->navigation_handle()->set_base_url_for_data_url(
1185 entry.GetBaseURLForDataURL());
1186
1187 // Have the current renderer execute its beforeunload event if needed. If it 1188 // Have the current renderer execute its beforeunload event if needed. If it
1188 // is not needed then NavigationRequest::BeginNavigation should be directly 1189 // is not needed then NavigationRequest::BeginNavigation should be directly
1189 // called instead. 1190 // called instead.
1190 if (should_dispatch_beforeunload && !IsRendererDebugURL(dest_url)) { 1191 if (should_dispatch_beforeunload && !IsRendererDebugURL(dest_url)) {
1191 navigation_request->SetWaitingForRendererResponse(); 1192 navigation_request->SetWaitingForRendererResponse();
1192 frame_tree_node->current_frame_host()->DispatchBeforeUnload( 1193 frame_tree_node->current_frame_host()->DispatchBeforeUnload(
1193 true, reload_type != ReloadType::NONE); 1194 true, reload_type != ReloadType::NONE);
1194 } else { 1195 } else {
1195 navigation_request->BeginNavigation(); 1196 navigation_request->BeginNavigation();
1196 } 1197 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 if (navigation_handle) 1298 if (navigation_handle)
1298 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); 1299 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID());
1299 1300
1300 controller_->SetPendingEntry(std::move(entry)); 1301 controller_->SetPendingEntry(std::move(entry));
1301 if (delegate_) 1302 if (delegate_)
1302 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); 1303 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL);
1303 } 1304 }
1304 } 1305 }
1305 1306
1306 } // namespace content 1307 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/navigator_impl.h ('k') | content/browser/frame_host/render_frame_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698