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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 } | 308 } |
| 309 | 309 |
| 310 bool NavigatorImpl::NavigateToEntry( | 310 bool NavigatorImpl::NavigateToEntry( |
| 311 FrameTreeNode* frame_tree_node, | 311 FrameTreeNode* frame_tree_node, |
| 312 const FrameNavigationEntry& frame_entry, | 312 const FrameNavigationEntry& frame_entry, |
| 313 const NavigationEntryImpl& entry, | 313 const NavigationEntryImpl& entry, |
| 314 ReloadType reload_type, | 314 ReloadType reload_type, |
| 315 bool is_same_document_history_load, | 315 bool is_same_document_history_load, |
| 316 bool is_history_navigation_in_new_child, | 316 bool is_history_navigation_in_new_child, |
| 317 bool is_pending_entry, | 317 bool is_pending_entry, |
| 318 bool has_user_gesture, | |
| 318 const scoped_refptr<ResourceRequestBodyImpl>& post_body) { | 319 const scoped_refptr<ResourceRequestBodyImpl>& post_body) { |
| 319 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 320 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
| 320 | 321 |
| 321 GURL dest_url = frame_entry.url(); | 322 GURL dest_url = frame_entry.url(); |
| 322 Referrer dest_referrer = frame_entry.referrer(); | 323 Referrer dest_referrer = frame_entry.referrer(); |
| 323 if (reload_type == ReloadType::ORIGINAL_REQUEST_URL && | 324 if (reload_type == ReloadType::ORIGINAL_REQUEST_URL && |
| 324 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { | 325 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { |
| 325 // We may have been redirected when navigating to the current URL. | 326 // 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 | 327 // 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 | 328 // 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(); | 375 ->last_navigation_previews_state(); |
| 375 } else if (reload_type == ReloadType::DISABLE_LOFI_MODE) { | 376 } else if (reload_type == ReloadType::DISABLE_LOFI_MODE) { |
| 376 // Disable LoFi when asked for it explicitly. | 377 // Disable LoFi when asked for it explicitly. |
| 377 previews_state = PREVIEWS_NO_TRANSFORM; | 378 previews_state = PREVIEWS_NO_TRANSFORM; |
| 378 } | 379 } |
| 379 | 380 |
| 380 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. | 381 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
| 381 if (IsBrowserSideNavigationEnabled()) { | 382 if (IsBrowserSideNavigationEnabled()) { |
| 382 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, | 383 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, |
| 383 entry.restore_type())); | 384 entry.restore_type())); |
| 384 RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, | 385 RequestNavigation( |
| 385 entry, reload_type, previews_state, | 386 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| 386 is_same_document_history_load, | 387 reload_type, previews_state, is_same_document_history_load, |
| 387 is_history_navigation_in_new_child, navigation_start); | 388 is_history_navigation_in_new_child, has_user_gesture, |
| 389 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, |
| 510 false, // history navigation in new child. | |
| 511 true, // pending entry. | |
| 512 false, // user gesture. | |
| 513 nullptr); // post data. | |
| 508 } | 514 } |
| 509 | 515 |
| 510 bool NavigatorImpl::NavigateNewChildFrame( | 516 bool NavigatorImpl::NavigateNewChildFrame( |
| 511 RenderFrameHostImpl* render_frame_host, | 517 RenderFrameHostImpl* render_frame_host, |
| 518 bool is_renderer_initiated, | |
| 519 bool has_user_gesture, | |
| 512 const GURL& default_url) { | 520 const GURL& default_url) { |
| 513 NavigationEntryImpl* entry = | 521 NavigationEntryImpl* entry = |
| 514 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); | 522 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); |
| 515 if (!entry) | 523 if (!entry) |
| 516 return false; | 524 return false; |
| 517 | 525 |
| 518 FrameNavigationEntry* frame_entry = | 526 FrameNavigationEntry* frame_entry = |
| 519 entry->GetFrameEntry(render_frame_host->frame_tree_node()); | 527 entry->GetFrameEntry(render_frame_host->frame_tree_node()); |
| 520 if (!frame_entry) | 528 if (!frame_entry) |
| 521 return false; | 529 return false; |
| 522 | 530 |
| 531 entry->set_is_renderer_initiated(is_renderer_initiated); | |
| 532 | |
| 523 // Track how often history navigations load a different URL into a subframe | 533 // Track how often history navigations load a different URL into a subframe |
| 524 // than the frame's default URL. | 534 // than the frame's default URL. |
| 525 bool restoring_different_url = frame_entry->url() != default_url; | 535 bool restoring_different_url = frame_entry->url() != default_url; |
| 526 UMA_HISTOGRAM_BOOLEAN("SessionRestore.RestoredSubframeURL", | 536 UMA_HISTOGRAM_BOOLEAN("SessionRestore.RestoredSubframeURL", |
| 527 restoring_different_url); | 537 restoring_different_url); |
| 528 // If this frame's unique name uses a frame path, record the name length. | 538 // If this frame's unique name uses a frame path, record the name length. |
| 529 // If these names are long in practice, then a proposed plan to truncate | 539 // If these names are long in practice, then a proposed plan to truncate |
| 530 // unique names might affect restore behavior, since it is complex to deal | 540 // unique names might affect restore behavior, since it is complex to deal |
| 531 // with truncated names inside frame paths. | 541 // with truncated names inside frame paths. |
| 532 if (restoring_different_url) { | 542 if (restoring_different_url) { |
| 533 const std::string& unique_name = | 543 const std::string& unique_name = |
| 534 render_frame_host->frame_tree_node()->unique_name(); | 544 render_frame_host->frame_tree_node()->unique_name(); |
| 535 const char kFramePathPrefix[] = "<!--framePath "; | 545 const char kFramePathPrefix[] = "<!--framePath "; |
| 536 if (base::StartsWith(unique_name, kFramePathPrefix, | 546 if (base::StartsWith(unique_name, kFramePathPrefix, |
| 537 base::CompareCase::SENSITIVE)) { | 547 base::CompareCase::SENSITIVE)) { |
| 538 UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength", | 548 UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength", |
| 539 unique_name.size()); | 549 unique_name.size()); |
| 540 } | 550 } |
| 541 } | 551 } |
| 542 | 552 |
| 543 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, | 553 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, |
| 544 *entry, ReloadType::NONE, false, true, false, nullptr); | 554 *entry, ReloadType::NONE, |
| 555 false, // same document history load. | |
| 556 true, // history navigation in new child. | |
| 557 false, // pending entry. | |
| 558 has_user_gesture, | |
| 559 nullptr); // post data. | |
| 545 } | 560 } |
| 546 | 561 |
| 547 void NavigatorImpl::DidNavigate( | 562 void NavigatorImpl::DidNavigate( |
| 548 RenderFrameHostImpl* render_frame_host, | 563 RenderFrameHostImpl* render_frame_host, |
| 549 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 564 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 550 std::unique_ptr<NavigationHandleImpl> navigation_handle) { | 565 std::unique_ptr<NavigationHandleImpl> navigation_handle) { |
| 551 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 566 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
| 552 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); | 567 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
| 553 | 568 |
| 554 bool has_embedded_credentials = | 569 bool has_embedded_credentials = |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 // scratch. This works because we do not depend on |frame_entry| being inside | 965 // scratch. This works because we do not depend on |frame_entry| being inside |
| 951 // |entry| during NavigateToEntry. This will go away when we shortcut this | 966 // |entry| during NavigateToEntry. This will go away when we shortcut this |
| 952 // further in https://crbug.com/536906. | 967 // further in https://crbug.com/536906. |
| 953 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); | 968 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); |
| 954 if (!frame_entry) { | 969 if (!frame_entry) { |
| 955 frame_entry = new FrameNavigationEntry( | 970 frame_entry = new FrameNavigationEntry( |
| 956 node->unique_name(), -1, -1, nullptr, | 971 node->unique_name(), -1, -1, nullptr, |
| 957 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 972 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
| 958 referrer_to_use, method, -1); | 973 referrer_to_use, method, -1); |
| 959 } | 974 } |
| 960 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, | 975 NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, |
| 961 false, false, post_body); | 976 false, // same document history load |
| 977 false, // history navigation in new child. | |
| 978 false, // pending entry. | |
| 979 false, // user gesture. | |
| 980 post_body); | |
| 962 } | 981 } |
| 963 | 982 |
| 964 // PlzNavigate | 983 // PlzNavigate |
| 965 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, | 984 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
| 966 bool proceed) { | 985 bool proceed) { |
| 967 CHECK(IsBrowserSideNavigationEnabled()); | 986 CHECK(IsBrowserSideNavigationEnabled()); |
| 968 DCHECK(frame_tree_node); | 987 DCHECK(frame_tree_node); |
| 969 | 988 |
| 970 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 989 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
| 971 | 990 |
| 972 // The NavigationRequest may have been canceled while the renderer was | 991 // The NavigationRequest may have been canceled while the renderer was |
| 973 // executing the BeforeUnload event. | 992 // executing the BeforeUnload event. |
| 974 if (!navigation_request) | 993 if (!navigation_request) |
| 975 return; | 994 return; |
| 976 | 995 |
| 977 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, | 996 // A new navigation from the browser/renderer may have occurred. |
| 978 navigation_request->state()); | 997 if (navigation_request->state() != |
| 998 NavigationRequest::WAITING_FOR_RENDERER_RESPONSE) { | |
|
clamy
2017/02/21 13:46:36
If the result of BeforeUnload is not proceed, shou
| |
| 999 return; | |
| 1000 } | |
| 979 | 1001 |
| 980 // If the navigation is allowed to proceed, send the request to the IO thread. | 1002 // If the navigation is allowed to proceed, send the request to the IO thread. |
| 981 if (proceed) | 1003 if (proceed) |
| 982 navigation_request->BeginNavigation(); | 1004 navigation_request->BeginNavigation(); |
| 983 else | 1005 else |
| 984 CancelNavigation(frame_tree_node); | 1006 CancelNavigation(frame_tree_node); |
| 985 } | 1007 } |
| 986 | 1008 |
| 987 // PlzNavigate | 1009 // PlzNavigate |
| 988 void NavigatorImpl::OnBeginNavigation( | 1010 void NavigatorImpl::OnBeginNavigation( |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1153 // PlzNavigate | 1175 // PlzNavigate |
| 1154 void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, | 1176 void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, |
| 1155 const GURL& dest_url, | 1177 const GURL& dest_url, |
| 1156 const Referrer& dest_referrer, | 1178 const Referrer& dest_referrer, |
| 1157 const FrameNavigationEntry& frame_entry, | 1179 const FrameNavigationEntry& frame_entry, |
| 1158 const NavigationEntryImpl& entry, | 1180 const NavigationEntryImpl& entry, |
| 1159 ReloadType reload_type, | 1181 ReloadType reload_type, |
| 1160 PreviewsState previews_state, | 1182 PreviewsState previews_state, |
| 1161 bool is_same_document_history_load, | 1183 bool is_same_document_history_load, |
| 1162 bool is_history_navigation_in_new_child, | 1184 bool is_history_navigation_in_new_child, |
| 1185 bool has_user_gesture, | |
| 1163 base::TimeTicks navigation_start) { | 1186 base::TimeTicks navigation_start) { |
| 1164 CHECK(IsBrowserSideNavigationEnabled()); | 1187 CHECK(IsBrowserSideNavigationEnabled()); |
| 1165 DCHECK(frame_tree_node); | 1188 DCHECK(frame_tree_node); |
| 1166 | 1189 |
| 1167 // This value must be set here because creating a NavigationRequest might | 1190 // This value must be set here because creating a NavigationRequest might |
| 1168 // change the renderer live/non-live status and change this result. | 1191 // change the renderer live/non-live status and change this result. |
| 1169 bool should_dispatch_beforeunload = | 1192 bool should_dispatch_beforeunload = |
| 1170 !is_same_document_history_load && | 1193 !is_same_document_history_load && |
| 1171 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); | 1194 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); |
| 1172 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( | 1195 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
| 1173 frame_tree_node->current_url(), // old_url | 1196 frame_tree_node->current_url(), // old_url |
| 1174 dest_url, // new_url | 1197 dest_url, // new_url |
| 1175 reload_type, // reload_type | 1198 reload_type, // reload_type |
| 1176 entry, // entry | 1199 entry, // entry |
| 1177 frame_entry, // frame_entry | 1200 frame_entry, // frame_entry |
| 1178 is_same_document_history_load); // is_same_document_history_load | 1201 is_same_document_history_load); // is_same_document_history_load |
| 1179 std::unique_ptr<NavigationRequest> scoped_request = | 1202 std::unique_ptr<NavigationRequest> scoped_request( |
| 1180 NavigationRequest::CreateBrowserInitiated( | 1203 NavigationRequest::CreateBrowserInitiated( |
| 1181 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, | 1204 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| 1182 navigation_type, previews_state, is_same_document_history_load, | 1205 navigation_type, previews_state, is_same_document_history_load, |
| 1183 is_history_navigation_in_new_child, navigation_start, controller_); | 1206 is_history_navigation_in_new_child, has_user_gesture, |
| 1207 navigation_start, controller_)); | |
| 1184 | 1208 |
| 1185 // Navigation to a javascript URL is not a "real" navigation so there is no | 1209 // 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 | 1210 // need to create a NavigationHandle. The navigation commits immediately and |
| 1187 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to | 1211 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to |
| 1188 // a Javascript URL should not interrupt a previous navigation. | 1212 // a Javascript URL should not interrupt a previous navigation. |
| 1189 // Note: The scoped_request will be destroyed at the end of this function. | 1213 // Note: The scoped_request will be destroyed at the end of this function. |
| 1190 if (dest_url.SchemeIs(url::kJavaScriptScheme)) { | 1214 if (dest_url.SchemeIs(url::kJavaScriptScheme)) { |
| 1191 RenderFrameHostImpl* render_frame_host = | 1215 RenderFrameHostImpl* render_frame_host = |
| 1192 frame_tree_node->render_manager()->GetFrameHostForNavigation( | 1216 frame_tree_node->render_manager()->GetFrameHostForNavigation( |
| 1193 *scoped_request.get()); | 1217 *scoped_request.get()); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1321 if (navigation_handle) | 1345 if (navigation_handle) |
| 1322 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); | 1346 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); |
| 1323 | 1347 |
| 1324 controller_->SetPendingEntry(std::move(entry)); | 1348 controller_->SetPendingEntry(std::move(entry)); |
| 1325 if (delegate_) | 1349 if (delegate_) |
| 1326 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); | 1350 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); |
| 1327 } | 1351 } |
| 1328 } | 1352 } |
| 1329 | 1353 |
| 1330 } // namespace content | 1354 } // namespace content |
| OLD | NEW |