Chromium Code Reviews| Index: content/browser/frame_host/navigator_impl.cc |
| diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc |
| index 997805938531dd69285fc32763d94d83c67f1a6c..2808c7c5834b78b729231522cc4b2f0785b8fe3b 100644 |
| --- a/content/browser/frame_host/navigator_impl.cc |
| +++ b/content/browser/frame_host/navigator_impl.cc |
| @@ -45,6 +45,7 @@ |
| #include "content/public/common/content_client.h" |
| #include "content/public/common/content_constants.h" |
| #include "content/public/common/resource_response.h" |
| +#include "net/base/load_flags.h" |
| #include "net/base/net_errors.h" |
| #include "url/gurl.h" |
| #include "url/url_util.h" |
| @@ -315,6 +316,7 @@ bool NavigatorImpl::NavigateToEntry( |
| bool is_same_document_history_load, |
| bool is_history_navigation_in_new_child, |
| bool is_pending_entry, |
| + bool is_user_gesture, |
| const scoped_refptr<ResourceRequestBodyImpl>& post_body) { |
| TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
| @@ -381,10 +383,10 @@ bool NavigatorImpl::NavigateToEntry( |
| if (IsBrowserSideNavigationEnabled()) { |
| navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, |
| entry.restore_type())); |
| - RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, |
| - entry, reload_type, previews_state, |
| - is_same_document_history_load, |
| - is_history_navigation_in_new_child, navigation_start); |
| + RequestNavigation( |
| + frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| + reload_type, previews_state, is_same_document_history_load, |
| + is_history_navigation_in_new_child, is_user_gesture, navigation_start); |
| if (frame_tree_node->IsMainFrame() && |
| frame_tree_node->navigation_request()) { |
| // TODO(carlosk): extend these traces to support subframes and |
| @@ -502,13 +504,14 @@ bool NavigatorImpl::NavigateToPendingEntry( |
| const FrameNavigationEntry& frame_entry, |
| ReloadType reload_type, |
| bool is_same_document_history_load) { |
| - return NavigateToEntry(frame_tree_node, frame_entry, |
| - *controller_->GetPendingEntry(), reload_type, |
| - is_same_document_history_load, false, true, nullptr); |
| + return NavigateToEntry( |
| + frame_tree_node, frame_entry, *controller_->GetPendingEntry(), |
| + reload_type, is_same_document_history_load, false, true, false, nullptr); |
| } |
| bool NavigatorImpl::NavigateNewChildFrame( |
| RenderFrameHostImpl* render_frame_host, |
| + bool is_user_gesture, |
| const GURL& default_url) { |
| NavigationEntryImpl* entry = |
| controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); |
| @@ -541,7 +544,8 @@ bool NavigatorImpl::NavigateNewChildFrame( |
| } |
| return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, |
| - *entry, ReloadType::NONE, false, true, false, nullptr); |
| + *entry, ReloadType::NONE, false, true, false, |
| + is_user_gesture, nullptr); |
| } |
| void NavigatorImpl::DidNavigate( |
| @@ -958,7 +962,7 @@ void NavigatorImpl::RequestTransferURL( |
| referrer_to_use, method, -1); |
| } |
| NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, |
| - false, false, post_body); |
| + false, false, false, post_body); |
| } |
| // PlzNavigate |
| @@ -974,8 +978,11 @@ void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
| if (!navigation_request) |
| return; |
| - DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, |
| - navigation_request->state()); |
| + // 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
|
| + if (navigation_request->state() != |
| + NavigationRequest::WAITING_FOR_RENDERER_RESPONSE) { |
| + return; |
| + } |
| // If the navigation is allowed to proceed, send the request to the IO thread. |
| if (proceed) |
| @@ -1160,6 +1167,7 @@ void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, |
| PreviewsState previews_state, |
| bool is_same_document_history_load, |
| bool is_history_navigation_in_new_child, |
| + bool is_user_gesture, |
| base::TimeTicks navigation_start) { |
| CHECK(IsBrowserSideNavigationEnabled()); |
| DCHECK(frame_tree_node); |
| @@ -1176,11 +1184,24 @@ void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, |
| entry, // entry |
| frame_entry, // frame_entry |
| is_same_document_history_load); // is_same_document_history_load |
| - std::unique_ptr<NavigationRequest> scoped_request = |
| - NavigationRequest::CreateBrowserInitiated( |
| - frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| - navigation_type, previews_state, is_same_document_history_load, |
| - is_history_navigation_in_new_child, navigation_start, controller_); |
| + |
| + std::unique_ptr<NavigationRequest> scoped_request; |
| + // We treat JS history navigations in child frame as renderer initiated |
| + // navigations. |
| + if (is_history_navigation_in_new_child && !is_user_gesture) { |
| + scoped_request = |
| + NavigationRequest::CreateRendererInitiatedHistoryNavigation( |
| + frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| + navigation_type, previews_state, is_history_navigation_in_new_child, |
| + is_user_gesture, navigation_start, controller_); |
| + } |
| + |
| + if (!scoped_request.get()) { |
| + scoped_request = NavigationRequest::CreateBrowserInitiated( |
| + frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
| + navigation_type, previews_state, is_same_document_history_load, |
| + is_history_navigation_in_new_child, navigation_start, controller_); |
| + } |
| // Navigation to a javascript URL is not a "real" navigation so there is no |
| // need to create a NavigationHandle. The navigation commits immediately and |