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/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 27 matching lines...) Expand all Loading... | |
| 38 #include "content/public/browser/navigation_details.h" | 38 #include "content/public/browser/navigation_details.h" |
| 39 #include "content/public/browser/page_navigator.h" | 39 #include "content/public/browser/page_navigator.h" |
| 40 #include "content/public/browser/render_view_host.h" | 40 #include "content/public/browser/render_view_host.h" |
| 41 #include "content/public/browser/stream_handle.h" | 41 #include "content/public/browser/stream_handle.h" |
| 42 #include "content/public/browser/user_metrics.h" | 42 #include "content/public/browser/user_metrics.h" |
| 43 #include "content/public/common/bindings_policy.h" | 43 #include "content/public/common/bindings_policy.h" |
| 44 #include "content/public/common/browser_side_navigation_policy.h" | 44 #include "content/public/common/browser_side_navigation_policy.h" |
| 45 #include "content/public/common/content_client.h" | 45 #include "content/public/common/content_client.h" |
| 46 #include "content/public/common/content_constants.h" | 46 #include "content/public/common/content_constants.h" |
| 47 #include "content/public/common/resource_response.h" | 47 #include "content/public/common/resource_response.h" |
| 48 #include "net/base/load_flags.h" | |
| 48 #include "net/base/net_errors.h" | 49 #include "net/base/net_errors.h" |
| 49 #include "url/gurl.h" | 50 #include "url/gurl.h" |
| 50 #include "url/url_util.h" | 51 #include "url/url_util.h" |
| 51 | 52 |
| 52 namespace content { | 53 namespace content { |
| 53 | 54 |
| 54 namespace { | 55 namespace { |
| 55 | 56 |
| 56 FrameMsg_Navigate_Type::Value GetNavigationType( | 57 FrameMsg_Navigate_Type::Value GetNavigationType( |
| 57 const GURL& old_url, | 58 const GURL& old_url, |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 } | 309 } |
| 309 | 310 |
| 310 bool NavigatorImpl::NavigateToEntry( | 311 bool NavigatorImpl::NavigateToEntry( |
| 311 FrameTreeNode* frame_tree_node, | 312 FrameTreeNode* frame_tree_node, |
| 312 const FrameNavigationEntry& frame_entry, | 313 const FrameNavigationEntry& frame_entry, |
| 313 const NavigationEntryImpl& entry, | 314 const NavigationEntryImpl& entry, |
| 314 ReloadType reload_type, | 315 ReloadType reload_type, |
| 315 bool is_same_document_history_load, | 316 bool is_same_document_history_load, |
| 316 bool is_history_navigation_in_new_child, | 317 bool is_history_navigation_in_new_child, |
| 317 bool is_pending_entry, | 318 bool is_pending_entry, |
| 319 bool is_user_gesture, | |
| 318 const scoped_refptr<ResourceRequestBodyImpl>& post_body) { | 320 const scoped_refptr<ResourceRequestBodyImpl>& post_body) { |
| 319 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 321 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
| 320 | 322 |
| 321 GURL dest_url = frame_entry.url(); | 323 GURL dest_url = frame_entry.url(); |
| 322 Referrer dest_referrer = frame_entry.referrer(); | 324 Referrer dest_referrer = frame_entry.referrer(); |
| 323 if (reload_type == ReloadType::ORIGINAL_REQUEST_URL && | 325 if (reload_type == ReloadType::ORIGINAL_REQUEST_URL && |
| 324 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { | 326 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { |
| 325 // We may have been redirected when navigating to the current URL. | 327 // We may have been redirected when navigating to the current URL. |
| 326 // Use the URL the user originally intended to visit, if it's valid and if a | 328 // Use the URL the user originally intended to visit, if it's valid and if a |
| 327 // POST wasn't involved; the latter case avoids issues with sending data to | 329 // POST wasn't involved; the latter case avoids issues with sending data to |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 ->last_navigation_previews_state(); | 376 ->last_navigation_previews_state(); |
| 375 } else if (reload_type == ReloadType::DISABLE_LOFI_MODE) { | 377 } else if (reload_type == ReloadType::DISABLE_LOFI_MODE) { |
| 376 // Disable LoFi when asked for it explicitly. | 378 // Disable LoFi when asked for it explicitly. |
| 377 previews_state = PREVIEWS_NO_TRANSFORM; | 379 previews_state = PREVIEWS_NO_TRANSFORM; |
| 378 } | 380 } |
| 379 | 381 |
| 380 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. | 382 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
| 381 if (IsBrowserSideNavigationEnabled()) { | 383 if (IsBrowserSideNavigationEnabled()) { |
| 382 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, | 384 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, |
| 383 entry.restore_type())); | 385 entry.restore_type())); |
| 384 RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, | 386 RequestNavigation( |
| 385 entry, reload_type, previews_state, | 387 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| 386 is_same_document_history_load, | 388 reload_type, previews_state, is_same_document_history_load, |
| 387 is_history_navigation_in_new_child, navigation_start); | 389 is_history_navigation_in_new_child, is_user_gesture, navigation_start); |
| 388 if (frame_tree_node->IsMainFrame() && | 390 if (frame_tree_node->IsMainFrame() && |
| 389 frame_tree_node->navigation_request()) { | 391 frame_tree_node->navigation_request()) { |
| 390 // TODO(carlosk): extend these traces to support subframes and | 392 // TODO(carlosk): extend these traces to support subframes and |
| 391 // non-PlzNavigate navigations. | 393 // non-PlzNavigate navigations. |
| 392 // For the trace below we're using the navigation handle as the async | 394 // For the trace below we're using the navigation handle as the async |
| 393 // trace id, |navigation_start| as the timestamp and reporting the | 395 // trace id, |navigation_start| as the timestamp and reporting the |
| 394 // FrameTreeNode id as a parameter. For navigations where no network | 396 // FrameTreeNode id as a parameter. For navigations where no network |
| 395 // request is made (data URLs, JavaScript URLs, etc) there is no handle | 397 // request is made (data URLs, JavaScript URLs, etc) there is no handle |
| 396 // and so no tracing is done. | 398 // and so no tracing is done. |
| 397 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( | 399 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); | 497 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); |
| 496 | 498 |
| 497 return true; | 499 return true; |
| 498 } | 500 } |
| 499 | 501 |
| 500 bool NavigatorImpl::NavigateToPendingEntry( | 502 bool NavigatorImpl::NavigateToPendingEntry( |
| 501 FrameTreeNode* frame_tree_node, | 503 FrameTreeNode* frame_tree_node, |
| 502 const FrameNavigationEntry& frame_entry, | 504 const FrameNavigationEntry& frame_entry, |
| 503 ReloadType reload_type, | 505 ReloadType reload_type, |
| 504 bool is_same_document_history_load) { | 506 bool is_same_document_history_load) { |
| 505 return NavigateToEntry(frame_tree_node, frame_entry, | 507 return NavigateToEntry( |
| 506 *controller_->GetPendingEntry(), reload_type, | 508 frame_tree_node, frame_entry, *controller_->GetPendingEntry(), |
| 507 is_same_document_history_load, false, true, nullptr); | 509 reload_type, is_same_document_history_load, false, true, false, nullptr); |
| 508 } | 510 } |
| 509 | 511 |
| 510 bool NavigatorImpl::NavigateNewChildFrame( | 512 bool NavigatorImpl::NavigateNewChildFrame( |
| 511 RenderFrameHostImpl* render_frame_host, | 513 RenderFrameHostImpl* render_frame_host, |
| 514 bool is_user_gesture, | |
| 512 const GURL& default_url) { | 515 const GURL& default_url) { |
| 513 NavigationEntryImpl* entry = | 516 NavigationEntryImpl* entry = |
| 514 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); | 517 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); |
| 515 if (!entry) | 518 if (!entry) |
| 516 return false; | 519 return false; |
| 517 | 520 |
| 518 FrameNavigationEntry* frame_entry = | 521 FrameNavigationEntry* frame_entry = |
| 519 entry->GetFrameEntry(render_frame_host->frame_tree_node()); | 522 entry->GetFrameEntry(render_frame_host->frame_tree_node()); |
| 520 if (!frame_entry) | 523 if (!frame_entry) |
| 521 return false; | 524 return false; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 534 render_frame_host->frame_tree_node()->unique_name(); | 537 render_frame_host->frame_tree_node()->unique_name(); |
| 535 const char kFramePathPrefix[] = "<!--framePath "; | 538 const char kFramePathPrefix[] = "<!--framePath "; |
| 536 if (base::StartsWith(unique_name, kFramePathPrefix, | 539 if (base::StartsWith(unique_name, kFramePathPrefix, |
| 537 base::CompareCase::SENSITIVE)) { | 540 base::CompareCase::SENSITIVE)) { |
| 538 UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength", | 541 UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength", |
| 539 unique_name.size()); | 542 unique_name.size()); |
| 540 } | 543 } |
| 541 } | 544 } |
| 542 | 545 |
| 543 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, | 546 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, |
| 544 *entry, ReloadType::NONE, false, true, false, nullptr); | 547 *entry, ReloadType::NONE, false, true, false, |
| 548 is_user_gesture, nullptr); | |
| 545 } | 549 } |
| 546 | 550 |
| 547 void NavigatorImpl::DidNavigate( | 551 void NavigatorImpl::DidNavigate( |
| 548 RenderFrameHostImpl* render_frame_host, | 552 RenderFrameHostImpl* render_frame_host, |
| 549 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 553 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 550 std::unique_ptr<NavigationHandleImpl> navigation_handle) { | 554 std::unique_ptr<NavigationHandleImpl> navigation_handle) { |
| 551 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 555 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
| 552 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); | 556 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
| 553 | 557 |
| 554 bool has_embedded_credentials = | 558 bool has_embedded_credentials = |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 951 // |entry| during NavigateToEntry. This will go away when we shortcut this | 955 // |entry| during NavigateToEntry. This will go away when we shortcut this |
| 952 // further in https://crbug.com/536906. | 956 // further in https://crbug.com/536906. |
| 953 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); | 957 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); |
| 954 if (!frame_entry) { | 958 if (!frame_entry) { |
| 955 frame_entry = new FrameNavigationEntry( | 959 frame_entry = new FrameNavigationEntry( |
| 956 node->unique_name(), -1, -1, nullptr, | 960 node->unique_name(), -1, -1, nullptr, |
| 957 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 961 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
| 958 referrer_to_use, method, -1); | 962 referrer_to_use, method, -1); |
| 959 } | 963 } |
| 960 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, | 964 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, |
| 961 false, false, post_body); | 965 false, false, false, post_body); |
| 962 } | 966 } |
| 963 | 967 |
| 964 // PlzNavigate | 968 // PlzNavigate |
| 965 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, | 969 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
| 966 bool proceed) { | 970 bool proceed) { |
| 967 CHECK(IsBrowserSideNavigationEnabled()); | 971 CHECK(IsBrowserSideNavigationEnabled()); |
| 968 DCHECK(frame_tree_node); | 972 DCHECK(frame_tree_node); |
| 969 | 973 |
| 970 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 974 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
| 971 | 975 |
| 972 // The NavigationRequest may have been canceled while the renderer was | 976 // The NavigationRequest may have been canceled while the renderer was |
| 973 // executing the BeforeUnload event. | 977 // executing the BeforeUnload event. |
| 974 if (!navigation_request) | 978 if (!navigation_request) |
| 975 return; | 979 return; |
| 976 | 980 |
| 977 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, | 981 // A new navigation may have occurred. |
|
clamy
2017/02/15 16:27:55
This seems wrong. If we started a new browser-init
ananta
2017/02/15 23:45:02
The scenario is the following:-
1. A browser navig
| |
| 978 navigation_request->state()); | 982 if (navigation_request->state() != |
| 983 NavigationRequest::WAITING_FOR_RENDERER_RESPONSE) { | |
| 984 return; | |
| 985 } | |
| 979 | 986 |
| 980 // If the navigation is allowed to proceed, send the request to the IO thread. | 987 // If the navigation is allowed to proceed, send the request to the IO thread. |
| 981 if (proceed) | 988 if (proceed) |
| 982 navigation_request->BeginNavigation(); | 989 navigation_request->BeginNavigation(); |
| 983 else | 990 else |
| 984 CancelNavigation(frame_tree_node); | 991 CancelNavigation(frame_tree_node); |
| 985 } | 992 } |
| 986 | 993 |
| 987 // PlzNavigate | 994 // PlzNavigate |
| 988 void NavigatorImpl::OnBeginNavigation( | 995 void NavigatorImpl::OnBeginNavigation( |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1153 // PlzNavigate | 1160 // PlzNavigate |
| 1154 void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, | 1161 void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, |
| 1155 const GURL& dest_url, | 1162 const GURL& dest_url, |
| 1156 const Referrer& dest_referrer, | 1163 const Referrer& dest_referrer, |
| 1157 const FrameNavigationEntry& frame_entry, | 1164 const FrameNavigationEntry& frame_entry, |
| 1158 const NavigationEntryImpl& entry, | 1165 const NavigationEntryImpl& entry, |
| 1159 ReloadType reload_type, | 1166 ReloadType reload_type, |
| 1160 PreviewsState previews_state, | 1167 PreviewsState previews_state, |
| 1161 bool is_same_document_history_load, | 1168 bool is_same_document_history_load, |
| 1162 bool is_history_navigation_in_new_child, | 1169 bool is_history_navigation_in_new_child, |
| 1170 bool is_user_gesture, | |
| 1163 base::TimeTicks navigation_start) { | 1171 base::TimeTicks navigation_start) { |
| 1164 CHECK(IsBrowserSideNavigationEnabled()); | 1172 CHECK(IsBrowserSideNavigationEnabled()); |
| 1165 DCHECK(frame_tree_node); | 1173 DCHECK(frame_tree_node); |
| 1166 | 1174 |
| 1167 // This value must be set here because creating a NavigationRequest might | 1175 // This value must be set here because creating a NavigationRequest might |
| 1168 // change the renderer live/non-live status and change this result. | 1176 // change the renderer live/non-live status and change this result. |
| 1169 bool should_dispatch_beforeunload = | 1177 bool should_dispatch_beforeunload = |
| 1170 !is_same_document_history_load && | 1178 !is_same_document_history_load && |
| 1171 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); | 1179 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); |
| 1172 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( | 1180 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
| 1173 frame_tree_node->current_url(), // old_url | 1181 frame_tree_node->current_url(), // old_url |
| 1174 dest_url, // new_url | 1182 dest_url, // new_url |
| 1175 reload_type, // reload_type | 1183 reload_type, // reload_type |
| 1176 entry, // entry | 1184 entry, // entry |
| 1177 frame_entry, // frame_entry | 1185 frame_entry, // frame_entry |
| 1178 is_same_document_history_load); // is_same_document_history_load | 1186 is_same_document_history_load); // is_same_document_history_load |
| 1179 std::unique_ptr<NavigationRequest> scoped_request = | 1187 |
| 1180 NavigationRequest::CreateBrowserInitiated( | 1188 std::unique_ptr<NavigationRequest> scoped_request; |
| 1181 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, | 1189 // We treat JS history navigations in child frame as renderer initiated |
| 1182 navigation_type, previews_state, is_same_document_history_load, | 1190 // navigations. |
| 1183 is_history_navigation_in_new_child, navigation_start, controller_); | 1191 if (is_history_navigation_in_new_child && !is_user_gesture) { |
| 1192 scoped_request = | |
| 1193 NavigationRequest::CreateRendererInitiatedHistoryNavigation( | |
| 1194 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, | |
| 1195 navigation_type, previews_state, is_history_navigation_in_new_child, | |
| 1196 is_user_gesture, navigation_start, controller_); | |
| 1197 } | |
| 1198 | |
| 1199 if (!scoped_request.get()) { | |
| 1200 scoped_request = NavigationRequest::CreateBrowserInitiated( | |
| 1201 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, | |
| 1202 navigation_type, previews_state, is_same_document_history_load, | |
| 1203 is_history_navigation_in_new_child, navigation_start, controller_); | |
| 1204 } | |
| 1184 | 1205 |
| 1185 // Navigation to a javascript URL is not a "real" navigation so there is no | 1206 // Navigation to a javascript URL is not a "real" navigation so there is no |
| 1186 // need to create a NavigationHandle. The navigation commits immediately and | 1207 // need to create a NavigationHandle. The navigation commits immediately and |
| 1187 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to | 1208 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to |
| 1188 // a Javascript URL should not interrupt a previous navigation. | 1209 // a Javascript URL should not interrupt a previous navigation. |
| 1189 // Note: The scoped_request will be destroyed at the end of this function. | 1210 // Note: The scoped_request will be destroyed at the end of this function. |
| 1190 if (dest_url.SchemeIs(url::kJavaScriptScheme)) { | 1211 if (dest_url.SchemeIs(url::kJavaScriptScheme)) { |
| 1191 RenderFrameHostImpl* render_frame_host = | 1212 RenderFrameHostImpl* render_frame_host = |
| 1192 frame_tree_node->render_manager()->GetFrameHostForNavigation( | 1213 frame_tree_node->render_manager()->GetFrameHostForNavigation( |
| 1193 *scoped_request.get()); | 1214 *scoped_request.get()); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1321 if (navigation_handle) | 1342 if (navigation_handle) |
| 1322 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); | 1343 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); |
| 1323 | 1344 |
| 1324 controller_->SetPendingEntry(std::move(entry)); | 1345 controller_->SetPendingEntry(std::move(entry)); |
| 1325 if (delegate_) | 1346 if (delegate_) |
| 1326 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); | 1347 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); |
| 1327 } | 1348 } |
| 1328 } | 1349 } |
| 1329 | 1350 |
| 1330 } // namespace content | 1351 } // namespace content |
| OLD | NEW |