| Index: content/renderer/render_frame_impl.cc
|
| diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
| index 483608675455914e4ace741ab0db7531516795a2..b9e484c55739a3f9ac56ec39005bd6b56aa92a18 100644
|
| --- a/content/renderer/render_frame_impl.cc
|
| +++ b/content/renderer/render_frame_impl.cc
|
| @@ -456,23 +456,32 @@ WebURLRequest CreateURLRequestForNavigation(
|
| return request;
|
| }
|
|
|
| -void UpdateFrameNavigationTiming(WebFrame* frame,
|
| - base::TimeTicks browser_navigation_start,
|
| - base::TimeTicks renderer_navigation_start) {
|
| +base::TimeTicks SanitizeNavigationTiming(
|
| + base::TimeTicks browser_navigation_start) {
|
| // The browser provides the navigation_start time to bootstrap the
|
| // Navigation Timing information for the browser-initiated navigations. In
|
| // case of cross-process navigations, this carries over the time of
|
| // finishing the onbeforeunload handler of the previous page.
|
| + // |browser_navigation_start| is likely before this process existed, so we
|
| + // can't use InterProcessTimeTicksConverter. We need at least to ensure
|
| + // that the browser-side navigation start we set is not later than the one
|
| + // on the renderer side.
|
| + base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
|
| DCHECK(!browser_navigation_start.is_null());
|
| - if (frame->provisionalDataSource()) {
|
| - // |browser_navigation_start| is likely before this process existed, so we
|
| - // can't use InterProcessTimeTicksConverter. We need at least to ensure
|
| - // that the browser-side navigation start we set is not later than the one
|
| - // on the renderer side.
|
| - base::TimeTicks navigation_start = std::min(
|
| - browser_navigation_start, renderer_navigation_start);
|
| + base::TimeTicks navigation_start =
|
| + std::min(browser_navigation_start, renderer_navigation_start);
|
| + // TODO(csharrison) UMA log:
|
| + // |renderer_navigation_start - browser_navigation_start|
|
| + return navigation_start;
|
| +}
|
| +
|
| +// Update the navigation start based on a better value recieved from the
|
| +// browser. This can be null if the timestamp should not be updated.
|
| +void UpdateFrameNavigationTiming(WebFrame* frame,
|
| + base::TimeTicks updated_navigation_start) {
|
| + if (frame->provisionalDataSource() && !updated_navigation_start.is_null()) {
|
| double navigation_start_seconds =
|
| - (navigation_start - base::TimeTicks()).InSecondsF();
|
| + (updated_navigation_start - base::TimeTicks()).InSecondsF();
|
| frame->provisionalDataSource()->setNavigationStartTime(
|
| navigation_start_seconds);
|
| // TODO(clamy): We need to provide additional timing values for the
|
| @@ -480,10 +489,12 @@ void UpdateFrameNavigationTiming(WebFrame* frame,
|
| }
|
| }
|
|
|
| +
|
| // PlzNavigate
|
| CommonNavigationParams MakeCommonNavigationParams(
|
| blink::WebURLRequest* request,
|
| - bool should_replace_current_entry) {
|
| + bool should_replace_current_entry,
|
| + const base::TimeTicks& navigation_start) {
|
| const RequestExtraData kEmptyData;
|
| const RequestExtraData* extra_data =
|
| static_cast<RequestExtraData*>(request->extraData());
|
| @@ -507,7 +518,8 @@ CommonNavigationParams MakeCommonNavigationParams(
|
| return CommonNavigationParams(
|
| request->url(), referrer, extra_data->transition_type(),
|
| FrameMsg_Navigate_Type::NORMAL, true, should_replace_current_entry,
|
| - ui_timestamp, report_type, GURL(), GURL(), LOFI_UNSPECIFIED);
|
| + ui_timestamp, report_type, GURL(), GURL(), LOFI_UNSPECIFIED,
|
| + navigation_start);
|
| }
|
|
|
| #if !defined(OS_ANDROID) || defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
|
| @@ -2699,12 +2711,28 @@ void RenderFrameImpl::didStartProvisionalLoad(blink::WebLocalFrame* frame,
|
| ->set_transition_type(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
|
| }
|
|
|
| + // Get the renderer navigation start in TimeTicks format. This will be
|
| + // lossy because blink converts TimeTicks internal int64 representation to a
|
| + // double.
|
| + DCHECK(ds->getNavigationStartTime());
|
| + base::TimeTicks navigation_start = base::TimeTicks::FromInternalValue(
|
| + ds->getNavigationStartTime() * base::Time::kMicrosecondsPerSecond);
|
| + // See if we have a better timestamp from a browser initiated navigation.
|
| + // If so, override it. This will be propogated to blink after the request has
|
| + // been issued.
|
| + if (ds->request().extraData()) {
|
| + RequestExtraData* extra_data =
|
| + static_cast<RequestExtraData*>(ds->request().extraData());
|
| + if (!extra_data->browser_navigation_start().is_null())
|
| + navigation_start = extra_data->browser_navigation_start();
|
| + }
|
| +
|
| FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(),
|
| DidStartProvisionalLoad(frame));
|
| FOR_EACH_OBSERVER(RenderFrameObserver, observers_, DidStartProvisionalLoad());
|
|
|
| Send(new FrameHostMsg_DidStartProvisionalLoadForFrame(
|
| - routing_id_, ds->request().url()));
|
| + routing_id_, ds->request().url(), navigation_start));
|
| }
|
|
|
| void RenderFrameImpl::didReceiveServerRedirectForProvisionalLoad(
|
| @@ -3352,10 +3380,12 @@ void RenderFrameImpl::willSendRequest(
|
| WebString custom_user_agent;
|
| WebString requested_with;
|
| scoped_ptr<StreamOverrideParameters> stream_override;
|
| + base::TimeTicks navigation_start;
|
| if (request.extraData()) {
|
| RequestExtraData* old_extra_data =
|
| static_cast<RequestExtraData*>(request.extraData());
|
|
|
| + navigation_start = old_extra_data->browser_navigation_start();
|
| custom_user_agent = old_extra_data->custom_user_agent();
|
| if (!custom_user_agent.isNull()) {
|
| if (custom_user_agent.isEmpty())
|
| @@ -3450,6 +3480,7 @@ void RenderFrameImpl::willSendRequest(
|
| navigation_state->start_params().transferred_request_request_id);
|
| extra_data->set_service_worker_provider_id(provider_id);
|
| extra_data->set_stream_override(stream_override.Pass());
|
| + extra_data->set_browser_navigation_start(navigation_start);
|
| if (request.loFiState() != WebURLRequest::LoFiUnspecified)
|
| extra_data->set_lofi_state(static_cast<LoFiState>(request.loFiState()));
|
| else if (is_main_frame_ && !navigation_state->request_committed())
|
| @@ -4304,10 +4335,8 @@ void RenderFrameImpl::OnFailedNavigation(
|
| pending_navigation_params_.reset(new NavigationParams(
|
| common_params, StartNavigationParams(), request_params));
|
|
|
| - // Inform the browser of the start of the provisional load. This is needed so
|
| - // that the load is properly tracked by the WebNavigation API.
|
| Send(new FrameHostMsg_DidStartProvisionalLoadForFrame(
|
| - routing_id_, common_params.url));
|
| + routing_id_, common_params.url, common_params.navigation_start));
|
|
|
| // Send the provisional load failure.
|
| blink::WebURLError error =
|
| @@ -4649,7 +4678,8 @@ void RenderFrameImpl::NavigateInternal(
|
| bool should_load_request = false;
|
| WebHistoryItem item_for_history_navigation;
|
| WebURLRequest request = CreateURLRequestForNavigation(
|
| - common_params, stream_params.Pass(), frame_->isViewSourceModeEnabled());
|
| + common_params, stream_params.Pass(),
|
| + frame_->isViewSourceModeEnabled());
|
| #if defined(OS_ANDROID)
|
| request.setHasUserGesture(start_params.has_user_gesture);
|
| #endif
|
| @@ -4774,9 +4804,13 @@ void RenderFrameImpl::NavigateInternal(
|
| }
|
|
|
| if (should_load_request) {
|
| - // Record this before starting the load. We need a lower bound of this
|
| - // time to sanitize the navigationStart override set below.
|
| - base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
|
| + base::TimeTicks updated_navigation_start;
|
| + if (load_type == blink::WebFrameLoadType::Standard) {
|
| + updated_navigation_start =
|
| + SanitizeNavigationTiming(common_params.navigation_start);
|
| + static_cast<RequestExtraData*>(request.extraData())
|
| + ->set_browser_navigation_start(updated_navigation_start);
|
| + }
|
|
|
| // Perform a navigation to a data url if needed.
|
| if (!common_params.base_url_for_data_url.is_empty() ||
|
| @@ -4788,12 +4822,8 @@ void RenderFrameImpl::NavigateInternal(
|
| frame_->toWebLocalFrame()->load(request, load_type,
|
| item_for_history_navigation);
|
| }
|
| -
|
| - if (load_type == blink::WebFrameLoadType::Standard) {
|
| - UpdateFrameNavigationTiming(frame_,
|
| - request_params.browser_navigation_start,
|
| - renderer_navigation_start);
|
| - }
|
| + // Update the navigationStart value after the request has been made.
|
| + UpdateFrameNavigationTiming(frame_, updated_navigation_start);
|
| }
|
|
|
| // In case LoadRequest failed before didCreateDataSource was called.
|
| @@ -4984,6 +5014,9 @@ void RenderFrameImpl::BeginNavigation(blink::WebURLRequest* request) {
|
| // TODO(clamy): Apply devtools override.
|
| // TODO(clamy): Make sure that navigation requests are not modified somewhere
|
| // else in blink.
|
| +
|
| + base::TimeTicks navigation_start = base::TimeTicks::Now();
|
| +
|
| willSendRequest(frame_, 0, *request, blink::WebURLResponse());
|
|
|
| // TODO(clamy): Same-document navigations should not be sent back to the
|
| @@ -5017,8 +5050,8 @@ void RenderFrameImpl::BeginNavigation(blink::WebURLRequest* request) {
|
| REQUEST_CONTEXT_FRAME_TYPE_NESTED);
|
|
|
| Send(new FrameHostMsg_BeginNavigation(
|
| - routing_id_,
|
| - MakeCommonNavigationParams(request, should_replace_current_entry),
|
| + routing_id_, MakeCommonNavigationParams(
|
| + request, should_replace_current_entry, navigation_start),
|
| BeginNavigationParams(
|
| request->httpMethod().latin1(), GetWebURLRequestHeaders(*request),
|
| GetLoadFlagsForWebURLRequest(*request), request->hasUserGesture(),
|
|
|