Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 1409883008: (Reland) set navigationStart based on CommonNavigationParams (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 // passed back to the browser in the DidCommitProvisionalLoad and the 448 // passed back to the browser in the DidCommitProvisionalLoad and the
449 // DocumentLoadComplete IPCs. 449 // DocumentLoadComplete IPCs.
450 base::TimeDelta ui_timestamp = common_params.ui_timestamp - base::TimeTicks(); 450 base::TimeDelta ui_timestamp = common_params.ui_timestamp - base::TimeTicks();
451 request.setUiStartTime(ui_timestamp.InSecondsF()); 451 request.setUiStartTime(ui_timestamp.InSecondsF());
452 request.setInputPerfMetricReportPolicy( 452 request.setInputPerfMetricReportPolicy(
453 static_cast<WebURLRequest::InputToLoadPerfMetricReportPolicy>( 453 static_cast<WebURLRequest::InputToLoadPerfMetricReportPolicy>(
454 common_params.report_type)); 454 common_params.report_type));
455 return request; 455 return request;
456 } 456 }
457 457
458 void UpdateFrameNavigationTiming(WebFrame* frame, 458 // Sanitizes the navigation_start timestamp for browser-initiated navigations,
459 base::TimeTicks browser_navigation_start, 459 // where the browser possibly has a better notion of start time than the
460 base::TimeTicks renderer_navigation_start) { 460 // renderer. In the case of cross-process navigations, this carries over the
461 // The browser provides the navigation_start time to bootstrap the 461 // time of finishing the onbeforeunload handler of the previous page.
462 // Navigation Timing information for the browser-initiated navigations. In 462 // TimeTicks is sometimes not monotonic across processes, and because
463 // case of cross-process navigations, this carries over the time of 463 // |browser_navigation_start| is likely before this process existed,
464 // finishing the onbeforeunload handler of the previous page. 464 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by
465 // clamping it to renderer_navigation_start, initialized earlier in the call
466 // stack.
467 base::TimeTicks SanitizeNavigationTiming(
468 blink::WebFrameLoadType load_type,
469 const base::TimeTicks& browser_navigation_start,
470 const base::TimeTicks& renderer_navigation_start) {
471 if (load_type != blink::WebFrameLoadType::Standard)
472 return base::TimeTicks();
465 DCHECK(!browser_navigation_start.is_null()); 473 DCHECK(!browser_navigation_start.is_null());
466 if (frame->provisionalDataSource()) { 474 base::TimeTicks navigation_start =
467 // |browser_navigation_start| is likely before this process existed, so we 475 std::min(browser_navigation_start, renderer_navigation_start);
468 // can't use InterProcessTimeTicksConverter. We need at least to ensure 476 // TODO(csharrison) Investigate how big a problem the cross process
469 // that the browser-side navigation start we set is not later than the one 477 // monotonicity really is and on what platforms. Log UMA for:
470 // on the renderer side. 478 // |renderer_navigation_start - browser_navigation_start|
471 base::TimeTicks navigation_start = std::min( 479 return navigation_start;
472 browser_navigation_start, renderer_navigation_start);
473 double navigation_start_seconds =
474 (navigation_start - base::TimeTicks()).InSecondsF();
475 frame->provisionalDataSource()->setNavigationStartTime(
476 navigation_start_seconds);
477 // TODO(clamy): We need to provide additional timing values for the
478 // Navigation Timing API to work with browser-side navigations.
479 }
480 } 480 }
481 481
482 // PlzNavigate 482 // PlzNavigate
483 CommonNavigationParams MakeCommonNavigationParams( 483 CommonNavigationParams MakeCommonNavigationParams(
484 blink::WebURLRequest* request, 484 blink::WebURLRequest* request,
485 bool should_replace_current_entry) { 485 bool should_replace_current_entry) {
486 const RequestExtraData kEmptyData; 486 const RequestExtraData kEmptyData;
487 const RequestExtraData* extra_data = 487 const RequestExtraData* extra_data =
488 static_cast<RequestExtraData*>(request->extraData()); 488 static_cast<RequestExtraData*>(request->extraData());
489 if (!extra_data) 489 if (!extra_data)
(...skipping 2108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 InternalDocumentStateData::FromDocumentState(document_state); 2598 InternalDocumentStateData::FromDocumentState(document_state);
2599 InternalDocumentStateData* old_internal_data = 2599 InternalDocumentStateData* old_internal_data =
2600 InternalDocumentStateData::FromDocumentState(old_document_state); 2600 InternalDocumentStateData::FromDocumentState(old_document_state);
2601 internal_data->set_is_overriding_user_agent( 2601 internal_data->set_is_overriding_user_agent(
2602 old_internal_data->is_overriding_user_agent()); 2602 old_internal_data->is_overriding_user_agent());
2603 } 2603 }
2604 } 2604 }
2605 2605
2606 // The rest of RenderView assumes that a WebDataSource will always have a 2606 // The rest of RenderView assumes that a WebDataSource will always have a
2607 // non-null NavigationState. 2607 // non-null NavigationState.
2608 if (content_initiated) { 2608 UpdateNavigationState(document_state);
2609 document_state->set_navigation_state(
2610 NavigationStateImpl::CreateContentInitiated());
2611 } else {
2612 document_state->set_navigation_state(CreateNavigationStateFromPending());
2613 pending_navigation_params_.reset();
2614 }
2615 2609
2616 // DocumentState::referred_by_prefetcher_ is true if we are 2610 // DocumentState::referred_by_prefetcher_ is true if we are
2617 // navigating from a page that used prefetching using a link on that 2611 // navigating from a page that used prefetching using a link on that
2618 // page. We are early enough in the request process here that we 2612 // page. We are early enough in the request process here that we
2619 // can still see the DocumentState of the previous page and set 2613 // can still see the DocumentState of the previous page and set
2620 // this value appropriately. 2614 // this value appropriately.
2621 // TODO(gavinp): catch the important case of navigation in a new 2615 // TODO(gavinp): catch the important case of navigation in a new
2622 // renderer process. 2616 // renderer process.
2623 if (webview) { 2617 if (webview) {
2624 if (WebFrame* old_frame = webview->mainFrame()) { 2618 if (WebFrame* old_frame = webview->mainFrame()) {
(...skipping 29 matching lines...) Expand all
2654 document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_STALE_OK); 2648 document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_STALE_OK);
2655 break; 2649 break;
2656 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post. 2650 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
2657 document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_ONLY); 2651 document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_ONLY);
2658 break; 2652 break;
2659 default: 2653 default:
2660 NOTREACHED(); 2654 NOTREACHED();
2661 } 2655 }
2662 } 2656 }
2663 2657
2658 NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
2659 document_state->navigation_state());
2660
2661 // Set the navigation start time in blink.
2662 base::TimeTicks navigation_start =
2663 navigation_state->common_params().navigation_start;
2664 datasource->setNavigationStartTime(
2665 (navigation_start - base::TimeTicks()).InSecondsF());
2666 // TODO(clamy) We need to provide additional timing values for the Navigation
2667 // Timing API to work with browser-side navigations.
2668
2664 // Create the serviceworker's per-document network observing object if it 2669 // Create the serviceworker's per-document network observing object if it
2665 // does not exist (When navigation happens within a page, the provider already 2670 // does not exist (When navigation happens within a page, the provider already
2666 // exists). 2671 // exists).
2667 if (ServiceWorkerNetworkProvider::FromDocumentState( 2672 if (ServiceWorkerNetworkProvider::FromDocumentState(
2668 DocumentState::FromDataSource(datasource))) 2673 DocumentState::FromDataSource(datasource)))
2669 return; 2674 return;
2670 2675
2671 NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
2672 DocumentState::FromDataSource(datasource)->navigation_state());
2673
2674 ServiceWorkerNetworkProvider::AttachToDocumentState( 2676 ServiceWorkerNetworkProvider::AttachToDocumentState(
2675 DocumentState::FromDataSource(datasource), 2677 DocumentState::FromDataSource(datasource),
2676 ServiceWorkerNetworkProvider::CreateForNavigation( 2678 ServiceWorkerNetworkProvider::CreateForNavigation(
2677 routing_id_, navigation_state->request_params(), 2679 routing_id_, navigation_state->request_params(),
2678 frame->effectiveSandboxFlags(), content_initiated)); 2680 frame->effectiveSandboxFlags(), content_initiated));
2679 } 2681 }
2680 2682
2681 void RenderFrameImpl::didStartProvisionalLoad(blink::WebLocalFrame* frame, 2683 void RenderFrameImpl::didStartProvisionalLoad(blink::WebLocalFrame* frame,
2682 double triggering_event_time) { 2684 double triggering_event_time) {
2683 DCHECK(!frame_ || frame_ == frame); 2685 DCHECK(!frame_ || frame_ == frame);
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
3148 blink::WebHistoryCommitType commit_type) { 3150 blink::WebHistoryCommitType commit_type) {
3149 TRACE_EVENT1("navigation", "RenderFrameImpl::didNavigateWithinPage", 3151 TRACE_EVENT1("navigation", "RenderFrameImpl::didNavigateWithinPage",
3150 "id", routing_id_); 3152 "id", routing_id_);
3151 DCHECK(!frame_ || frame_ == frame); 3153 DCHECK(!frame_ || frame_ == frame);
3152 // If this was a reference fragment navigation that we initiated, then we 3154 // If this was a reference fragment navigation that we initiated, then we
3153 // could end up having a non-null pending navigation params. We just need to 3155 // could end up having a non-null pending navigation params. We just need to
3154 // update the ExtraData on the datasource so that others who read the 3156 // update the ExtraData on the datasource so that others who read the
3155 // ExtraData will get the new NavigationState. Similarly, if we did not 3157 // ExtraData will get the new NavigationState. Similarly, if we did not
3156 // initiate this navigation, then we need to take care to reset any pre- 3158 // initiate this navigation, then we need to take care to reset any pre-
3157 // existing navigation state to a content-initiated navigation state. 3159 // existing navigation state to a content-initiated navigation state.
3158 // didCreateDataSource conveniently takes care of this for us. 3160 // UpdateNavigationState conveniently takes care of this for us.
3159 didCreateDataSource(frame, frame->dataSource());
3160
3161 DocumentState* document_state = 3161 DocumentState* document_state =
3162 DocumentState::FromDataSource(frame->dataSource()); 3162 DocumentState::FromDataSource(frame->dataSource());
3163 UpdateNavigationState(document_state);
3163 static_cast<NavigationStateImpl*>(document_state->navigation_state()) 3164 static_cast<NavigationStateImpl*>(document_state->navigation_state())
3164 ->set_was_within_same_page(true); 3165 ->set_was_within_same_page(true);
3165 3166
3166 didCommitProvisionalLoad(frame, item, commit_type); 3167 didCommitProvisionalLoad(frame, item, commit_type);
3167 } 3168 }
3168 3169
3169 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame) { 3170 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame) {
3170 DCHECK(!frame_ || frame_ == frame); 3171 DCHECK(!frame_ || frame_ == frame);
3171 // TODO(nasko): Move implementation here. Needed methods: 3172 // TODO(nasko): Move implementation here. Needed methods:
3172 // * StartNavStateSyncTimerIfNecessary 3173 // * StartNavStateSyncTimerIfNecessary
(...skipping 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after
4650 } 4651 }
4651 4652
4652 void RenderFrameImpl::NavigateInternal( 4653 void RenderFrameImpl::NavigateInternal(
4653 const CommonNavigationParams& common_params, 4654 const CommonNavigationParams& common_params,
4654 const StartNavigationParams& start_params, 4655 const StartNavigationParams& start_params,
4655 const RequestNavigationParams& request_params, 4656 const RequestNavigationParams& request_params,
4656 scoped_ptr<StreamOverrideParameters> stream_params) { 4657 scoped_ptr<StreamOverrideParameters> stream_params) {
4657 bool browser_side_navigation = 4658 bool browser_side_navigation =
4658 base::CommandLine::ForCurrentProcess()->HasSwitch( 4659 base::CommandLine::ForCurrentProcess()->HasSwitch(
4659 switches::kEnableBrowserSideNavigation); 4660 switches::kEnableBrowserSideNavigation);
4661
4662 // Lower bound for browser initiated navigation start time.
4663 base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
4660 bool is_reload = IsReload(common_params.navigation_type); 4664 bool is_reload = IsReload(common_params.navigation_type);
4661 bool is_history_navigation = request_params.page_state.IsValid(); 4665 bool is_history_navigation = request_params.page_state.IsValid();
4662 WebURLRequest::CachePolicy cache_policy = 4666 WebURLRequest::CachePolicy cache_policy =
4663 WebURLRequest::UseProtocolCachePolicy; 4667 WebURLRequest::UseProtocolCachePolicy;
4664 RenderFrameImpl::PrepareRenderViewForNavigation( 4668 RenderFrameImpl::PrepareRenderViewForNavigation(
4665 common_params.url, request_params, &is_reload, &cache_policy); 4669 common_params.url, request_params, &is_reload, &cache_policy);
4666 4670
4667 GetContentClient()->SetActiveURL(common_params.url); 4671 GetContentClient()->SetActiveURL(common_params.url);
4668 4672
4669 // If this frame isn't in the same process as the main frame, it may naively 4673 // If this frame isn't in the same process as the main frame, it may naively
(...skipping 10 matching lines...) Expand all
4680 if (is_reload && no_current_entry) { 4684 if (is_reload && no_current_entry) {
4681 // We cannot reload if we do not have any history state. This happens, for 4685 // We cannot reload if we do not have any history state. This happens, for
4682 // example, when recovering from a crash. 4686 // example, when recovering from a crash.
4683 is_reload = false; 4687 is_reload = false;
4684 cache_policy = WebURLRequest::ReloadIgnoringCacheData; 4688 cache_policy = WebURLRequest::ReloadIgnoringCacheData;
4685 } 4689 }
4686 4690
4687 pending_navigation_params_.reset( 4691 pending_navigation_params_.reset(
4688 new NavigationParams(common_params, start_params, request_params)); 4692 new NavigationParams(common_params, start_params, request_params));
4689 4693
4694 // Unless the load is a WebFrameLoadType::Standard, this should remain
4695 // uninitialized. It will be updated when the load type is determined to be
4696 // Standard, or after the previous document's unload handler has been
4697 // triggered. This occurs in UpdateNavigationState.
4698 // TODO(csharrison) See if we can always use the browser timestamp.
4699 pending_navigation_params_->common_params.navigation_start =
4700 base::TimeTicks();
4701
4690 // Create parameters for a standard navigation. 4702 // Create parameters for a standard navigation.
4691 blink::WebFrameLoadType load_type = blink::WebFrameLoadType::Standard; 4703 blink::WebFrameLoadType load_type = blink::WebFrameLoadType::Standard;
4692 bool should_load_request = false; 4704 bool should_load_request = false;
4693 WebHistoryItem item_for_history_navigation; 4705 WebHistoryItem item_for_history_navigation;
4694 WebURLRequest request = CreateURLRequestForNavigation( 4706 WebURLRequest request = CreateURLRequestForNavigation(
4695 common_params, stream_params.Pass(), frame_->isViewSourceModeEnabled()); 4707 common_params, stream_params.Pass(), frame_->isViewSourceModeEnabled());
4696 #if defined(OS_ANDROID) 4708 #if defined(OS_ANDROID)
4697 request.setHasUserGesture(start_params.has_user_gesture); 4709 request.setHasUserGesture(start_params.has_user_gesture);
4698 #endif 4710 #endif
4699 4711
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4804 request.setHTTPBody(http_body); 4816 request.setHTTPBody(http_body);
4805 } 4817 }
4806 4818
4807 // A session history navigation should have been accompanied by state. 4819 // A session history navigation should have been accompanied by state.
4808 CHECK_EQ(request_params.page_id, -1); 4820 CHECK_EQ(request_params.page_id, -1);
4809 4821
4810 should_load_request = true; 4822 should_load_request = true;
4811 } 4823 }
4812 4824
4813 if (should_load_request) { 4825 if (should_load_request) {
4814 // Record this before starting the load. We need a lower bound of this 4826 // Sanitize navigation start now that we know the load_type.
4815 // time to sanitize the navigationStart override set below. 4827 pending_navigation_params_->common_params.navigation_start =
4816 base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); 4828 SanitizeNavigationTiming(load_type, common_params.navigation_start,
4817 4829 renderer_navigation_start);
4818 // Perform a navigation to a data url if needed. 4830 // Perform a navigation to a data url if needed.
4819 if (!common_params.base_url_for_data_url.is_empty() || 4831 if (!common_params.base_url_for_data_url.is_empty() ||
4820 (browser_side_navigation && 4832 (browser_side_navigation &&
4821 common_params.url.SchemeIs(url::kDataScheme))) { 4833 common_params.url.SchemeIs(url::kDataScheme))) {
4822 LoadDataURL(common_params, frame_); 4834 LoadDataURL(common_params, frame_);
4823 } else { 4835 } else {
4824 // Load the request. 4836 // Load the request.
4825 frame_->toWebLocalFrame()->load(request, load_type, 4837 frame_->toWebLocalFrame()->load(request, load_type,
4826 item_for_history_navigation); 4838 item_for_history_navigation);
4827 } 4839 }
4828
4829 if (load_type == blink::WebFrameLoadType::Standard) {
4830 UpdateFrameNavigationTiming(frame_,
4831 common_params.navigation_start,
4832 renderer_navigation_start);
4833 }
4834 } 4840 }
4835 4841
4836 // In case LoadRequest failed before didCreateDataSource was called. 4842 // In case LoadRequest failed before didCreateDataSource was called.
4837 pending_navigation_params_.reset(); 4843 pending_navigation_params_.reset();
4838 } 4844 }
4839 4845
4840 void RenderFrameImpl::UpdateEncoding(WebFrame* frame, 4846 void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
4841 const std::string& encoding_name) { 4847 const std::string& encoding_name) {
4842 // Only update main frame's encoding_name. 4848 // Only update main frame's encoding_name.
4843 if (!frame->parent()) 4849 if (!frame->parent())
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
5193 NavigationState* RenderFrameImpl::CreateNavigationStateFromPending() { 5199 NavigationState* RenderFrameImpl::CreateNavigationStateFromPending() {
5194 if (IsBrowserInitiated(pending_navigation_params_.get())) { 5200 if (IsBrowserInitiated(pending_navigation_params_.get())) {
5195 return NavigationStateImpl::CreateBrowserInitiated( 5201 return NavigationStateImpl::CreateBrowserInitiated(
5196 pending_navigation_params_->common_params, 5202 pending_navigation_params_->common_params,
5197 pending_navigation_params_->start_params, 5203 pending_navigation_params_->start_params,
5198 pending_navigation_params_->request_params); 5204 pending_navigation_params_->request_params);
5199 } 5205 }
5200 return NavigationStateImpl::CreateContentInitiated(); 5206 return NavigationStateImpl::CreateContentInitiated();
5201 } 5207 }
5202 5208
5209 void RenderFrameImpl::UpdateNavigationState(DocumentState* document_state) {
5210 if (pending_navigation_params_) {
5211 // If this is a browser-initiated load that doesn't override
5212 // navigation_start, set it here.
5213 if (pending_navigation_params_->common_params.navigation_start.is_null()) {
5214 pending_navigation_params_->common_params.navigation_start =
5215 base::TimeTicks::Now();
5216 }
5217 document_state->set_navigation_state(CreateNavigationStateFromPending());
5218 pending_navigation_params_.reset();
5219 } else {
5220 document_state->set_navigation_state(
5221 NavigationStateImpl::CreateContentInitiated());
5222 }
5223 }
5224
5203 #if defined(OS_ANDROID) 5225 #if defined(OS_ANDROID)
5204 WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer( 5226 WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer(
5205 WebMediaPlayerClient* client, 5227 WebMediaPlayerClient* client,
5206 WebMediaPlayerEncryptedMediaClient* encrypted_client, 5228 WebMediaPlayerEncryptedMediaClient* encrypted_client,
5207 const media::WebMediaPlayerParams& params) { 5229 const media::WebMediaPlayerParams& params) {
5208 scoped_refptr<StreamTextureFactory> stream_texture_factory; 5230 scoped_refptr<StreamTextureFactory> stream_texture_factory;
5209 if (SynchronousCompositorFactory* factory = 5231 if (SynchronousCompositorFactory* factory =
5210 SynchronousCompositorFactory::GetInstance()) { 5232 SynchronousCompositorFactory::GetInstance()) {
5211 stream_texture_factory = factory->CreateStreamTextureFactory(routing_id_); 5233 stream_texture_factory = factory->CreateStreamTextureFactory(routing_id_);
5212 } else { 5234 } else {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
5330 mojo::ServiceProviderPtr service_provider; 5352 mojo::ServiceProviderPtr service_provider;
5331 mojo::URLRequestPtr request(mojo::URLRequest::New()); 5353 mojo::URLRequestPtr request(mojo::URLRequest::New());
5332 request->url = mojo::String::From(url); 5354 request->url = mojo::String::From(url);
5333 mojo_shell_->ConnectToApplication(request.Pass(), GetProxy(&service_provider), 5355 mojo_shell_->ConnectToApplication(request.Pass(), GetProxy(&service_provider),
5334 nullptr, nullptr, 5356 nullptr, nullptr,
5335 base::Bind(&OnGotContentHandlerID)); 5357 base::Bind(&OnGotContentHandlerID));
5336 return service_provider.Pass(); 5358 return service_provider.Pass();
5337 } 5359 }
5338 5360
5339 } // namespace content 5361 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698