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 ebd10e9739d85a3dbb38636447002fd1893e0df6..8e092e614898061b7b9054dab5bde674af7f93e7 100644 |
| --- a/content/browser/frame_host/navigator_impl.cc |
| +++ b/content/browser/frame_host/navigator_impl.cc |
| @@ -19,6 +19,7 @@ |
| #include "content/browser/site_instance_impl.h" |
| #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| #include "content/browser/webui/web_ui_impl.h" |
| +#include "content/common/frame_messages.h" |
| #include "content/common/navigation_params.h" |
| #include "content/common/view_messages.h" |
| #include "content/public/browser/browser_context.h" |
| @@ -37,8 +38,6 @@ |
| #include "content/public/common/resource_response.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/common/url_utils.h" |
| -#include "net/base/load_flags.h" |
| -#include "net/http/http_request_headers.h" |
| namespace content { |
| @@ -70,65 +69,6 @@ FrameMsg_Navigate_Type::Value GetNavigationType( |
| return FrameMsg_Navigate_Type::NORMAL; |
| } |
| -// PlzNavigate |
| -// Returns the net load flags to use based on the navigation type. |
| -// TODO(clamy): unify the code with what is happening on the renderer side. |
| -int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) { |
| - int load_flags = net::LOAD_NORMAL; |
| - switch (navigation_type) { |
| - case FrameMsg_Navigate_Type::RELOAD: |
| - case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL: |
| - load_flags |= net::LOAD_VALIDATE_CACHE; |
| - break; |
| - case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE: |
| - load_flags |= net::LOAD_BYPASS_CACHE; |
| - break; |
| - case FrameMsg_Navigate_Type::RESTORE: |
| - load_flags |= net::LOAD_PREFERRING_CACHE; |
| - break; |
| - case FrameMsg_Navigate_Type::RESTORE_WITH_POST: |
| - load_flags |= net::LOAD_ONLY_FROM_CACHE; |
| - break; |
| - case FrameMsg_Navigate_Type::NORMAL: |
| - default: |
| - break; |
| - } |
| - return load_flags; |
| -} |
| - |
| -// PlzNavigate |
| -// Generates a default FrameHostMsg_BeginNavigation_Params to be used when there |
| -// is no live renderer. |
| -FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation( |
| - const RequestNavigationParams& request_params, |
| - FrameMsg_Navigate_Type::Value navigation_type) { |
| - FrameHostMsg_BeginNavigation_Params begin_navigation_params; |
| - begin_navigation_params.method = request_params.is_post ? "POST" : "GET"; |
| - begin_navigation_params.load_flags = |
| - LoadFlagFromNavigationType(navigation_type); |
| - |
| - // Copy existing headers and add necessary headers that may not be present |
| - // in the RequestNavigationParams. |
| - net::HttpRequestHeaders headers; |
| - headers.AddHeadersFromString(request_params.extra_headers); |
| - headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent, |
| - GetContentClient()->GetUserAgent()); |
| - headers.SetHeaderIfMissing("Accept", "*/*"); |
| - begin_navigation_params.headers = headers.ToString(); |
| - |
| - // Fill POST data from the browser in the request body. |
| - if (request_params.is_post) { |
| - begin_navigation_params.request_body = new ResourceRequestBody(); |
| - begin_navigation_params.request_body->AppendBytes( |
| - reinterpret_cast<const char *>( |
| - &request_params.browser_initiated_post_data.front()), |
| - request_params.browser_initiated_post_data.size()); |
| - } |
| - |
| - begin_navigation_params.has_user_gesture = false; |
| - return begin_navigation_params; |
| -} |
| - |
| RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { |
| if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kSitePerProcess)) |
| @@ -746,10 +686,8 @@ void NavigatorImpl::RequestTransferURL( |
| } |
| // PlzNavigate |
| -void NavigatorImpl::OnBeginNavigation( |
| - FrameTreeNode* frame_tree_node, |
| - const FrameHostMsg_BeginNavigation_Params& params, |
| - const CommonNavigationParams& common_params) { |
| +void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
| + bool proceed) { |
| CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableBrowserSideNavigation)); |
| DCHECK(frame_tree_node); |
| @@ -757,43 +695,41 @@ void NavigatorImpl::OnBeginNavigation( |
| NavigationRequest* navigation_request = |
| navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); |
| - if (!navigation_request) { |
| - // This is a renderer initiated navigation, so generate a new |
| - // NavigationRequest and store it in the map. |
| - // TODO(clamy): Check if some PageState should be provided here. |
| - // TODO(clamy): See how we should handle override of the user agent when the |
| - // navigation may start in a renderer and commit in another one. |
| - // TODO(clamy): See if the navigation start time should be measured in the |
| - // renderer and sent to the browser instead of being measured here. |
| - scoped_ptr<NavigationRequest> scoped_request(new NavigationRequest( |
| - frame_tree_node, common_params, |
| - CommitNavigationParams(PageState(), false, base::TimeTicks::Now()), |
| - nullptr)); |
| - navigation_request = scoped_request.get(); |
| - navigation_request_map_.set( |
| - frame_tree_node->frame_tree_node_id(), scoped_request.Pass()); |
| - } |
| - DCHECK(navigation_request); |
| - |
| - // Update the referrer with the one received from the renderer. |
| - navigation_request->common_params().referrer = common_params.referrer; |
| + // The NavigationRequest may have been canceled while the renderer was |
| + // executing the BeforeUnload event. |
| + if (!navigation_request) |
| + return; |
| - scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params)); |
| + DCHECK(navigation_request->state() == |
| + 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.
|
| - info->first_party_for_cookies = |
| - frame_tree_node->IsMainFrame() |
| - ? navigation_request->common_params().url |
| - : frame_tree_node->frame_tree()->root()->current_url(); |
| - info->is_main_frame = frame_tree_node->IsMainFrame(); |
| - info->parent_is_main_frame = !frame_tree_node->parent() ? |
| - false : frame_tree_node->parent()->IsMainFrame(); |
| + if (proceed) |
| + BeginNavigation(frame_tree_node); |
| + else |
| + CancelNavigation(frame_tree_node); |
| +} |
| - // First start the request on the IO thread. |
| - navigation_request->BeginNavigation(info.Pass(), params.request_body); |
| +// PlzNavigate |
| +void NavigatorImpl::OnBeginNavigation( |
| + FrameTreeNode* frame_tree_node, |
| + const CommonNavigationParams& common_params, |
| + const BeginNavigationParams& begin_params, |
| + scoped_refptr<ResourceRequestBody> body) { |
| + CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kEnableBrowserSideNavigation)); |
| + DCHECK(frame_tree_node); |
| - // Then notify the RenderFrameHostManager so it can speculatively create a |
| - // RenderFrameHost (and potentially a new renderer process) in parallel. |
| - frame_tree_node->render_manager()->BeginNavigation(*navigation_request); |
| + // 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.
|
| + // NavigationRequest and store it in the map. |
| + // TODO(clamy): Renderer-initiated navigations should not always cancel the |
| + // current one. |
| + scoped_ptr<NavigationRequest> navigation_request = |
| + NavigationRequest::CreateRendererInitiated( |
| + frame_tree_node, common_params, begin_params, body); |
| + 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
|
| + frame_tree_node->frame_tree_node_id(), navigation_request.Pass()); |
| + |
| + BeginNavigation(frame_tree_node); |
| } |
| // PlzNavigate |
| @@ -905,35 +841,42 @@ bool NavigatorImpl::RequestNavigation( |
| int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
| FrameMsg_Navigate_Type::Value navigation_type = |
| GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
| - scoped_ptr<NavigationRequest> navigation_request = NavigationRequest::Create( |
| - frame_tree_node, entry, navigation_type, navigation_start); |
| - RequestNavigationParams request_params(entry.GetHasPostData(), |
| - entry.extra_headers(), |
| - entry.GetBrowserInitiatedPostData()); |
| + scoped_ptr<NavigationRequest> navigation_request = |
| + NavigationRequest::CreateBrowserInitiated( |
| + frame_tree_node, entry, navigation_type, navigation_start); |
| // TODO(clamy): Check if navigations are blocked and if so store the |
| // parameters. |
| // If there is an ongoing request, replace it. |
| navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); |
| - if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) { |
| - NavigationRequest* request_to_send = |
| - navigation_request_map_.get(frame_tree_node_id); |
| - frame_tree_node->current_frame_host()->Send(new FrameMsg_RequestNavigation( |
| - frame_tree_node->current_frame_host()->GetRoutingID(), |
| - request_to_send->common_params(), request_params)); |
| - request_to_send->SetWaitingForRendererResponse(); |
| - return true; |
| - } |
| - |
| - // The navigation request is sent directly to the IO thread. |
| - OnBeginNavigation( |
| - frame_tree_node, |
| - MakeDefaultBeginNavigation(request_params, navigation_type), |
| - navigation_request_map_.get(frame_tree_node_id)->common_params()); |
| + // 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.
|
| + // is not needed (eg. the renderer is not live), BeginNavigation should get |
| + // called. |
| + NavigationRequest* request_to_send = |
| + navigation_request_map_.get(frame_tree_node_id); |
| + request_to_send->SetWaitingForRendererResponse(); |
| + 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.
|
| 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
|
| } |
| +void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { |
| + NavigationRequest* navigation_request = |
| + navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); |
| + |
| + // A browser-initiated navigation could have been cancelled while it was |
| + // waiting for the BeforeUnload event to execute. |
| + if (!navigation_request) |
| + return; |
| + |
| + // First start the request on the IO thread. |
| + navigation_request->BeginNavigation(); |
| + |
| + // Then notify the RenderFrameHostManager so it can speculatively create a |
| + // RenderFrameHost (and potentially a new renderer process) in parallel. |
| + frame_tree_node->render_manager()->BeginNavigation(*navigation_request); |
| +} |
| + |
| void NavigatorImpl::RecordNavigationMetrics( |
| const LoadCommittedDetails& details, |
| const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |