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

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

Issue 2103733004: Set navigationStart correctly for all load types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Account for PlzNavigate. Created 4 years, 3 months 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 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 // Sanitizes the navigation_start timestamp for browser-initiated navigations, 572 // Sanitizes the navigation_start timestamp for browser-initiated navigations,
573 // where the browser possibly has a better notion of start time than the 573 // where the browser possibly has a better notion of start time than the
574 // renderer. In the case of cross-process navigations, this carries over the 574 // renderer. In the case of cross-process navigations, this carries over the
575 // time of finishing the onbeforeunload handler of the previous page. 575 // time of finishing the onbeforeunload handler of the previous page.
576 // TimeTicks is sometimes not monotonic across processes, and because 576 // TimeTicks is sometimes not monotonic across processes, and because
577 // |browser_navigation_start| is likely before this process existed, 577 // |browser_navigation_start| is likely before this process existed,
578 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by 578 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by
579 // clamping it to renderer_navigation_start, initialized earlier in the call 579 // clamping it to renderer_navigation_start, initialized earlier in the call
580 // stack. 580 // stack.
581 base::TimeTicks SanitizeNavigationTiming( 581 base::TimeTicks SanitizeNavigationTiming(
582 blink::WebFrameLoadType load_type,
583 const base::TimeTicks& browser_navigation_start, 582 const base::TimeTicks& browser_navigation_start,
584 const base::TimeTicks& renderer_navigation_start) { 583 const base::TimeTicks& renderer_navigation_start) {
585 if (load_type != blink::WebFrameLoadType::Standard)
586 return base::TimeTicks();
587 DCHECK(!browser_navigation_start.is_null()); 584 DCHECK(!browser_navigation_start.is_null());
588 base::TimeTicks navigation_start = 585 base::TimeTicks navigation_start =
589 std::min(browser_navigation_start, renderer_navigation_start); 586 std::min(browser_navigation_start, renderer_navigation_start);
590 base::TimeDelta difference = 587 base::TimeDelta difference =
591 renderer_navigation_start - browser_navigation_start; 588 renderer_navigation_start - browser_navigation_start;
592 if (difference > base::TimeDelta()) { 589 if (difference > base::TimeDelta()) {
593 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive", 590 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive",
594 difference); 591 difference);
595 } else { 592 } else {
596 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative", 593 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative",
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 effective_connection_type_( 1072 effective_connection_type_(
1076 blink::WebEffectiveConnectionType::TypeUnknown), 1073 blink::WebEffectiveConnectionType::TypeUnknown),
1077 is_pasting_(false), 1074 is_pasting_(false),
1078 suppress_further_dialogs_(false), 1075 suppress_further_dialogs_(false),
1079 blame_context_(nullptr), 1076 blame_context_(nullptr),
1080 #if defined(ENABLE_PLUGINS) 1077 #if defined(ENABLE_PLUGINS)
1081 focused_pepper_plugin_(nullptr), 1078 focused_pepper_plugin_(nullptr),
1082 pepper_last_mouse_event_target_(nullptr), 1079 pepper_last_mouse_event_target_(nullptr),
1083 #endif 1080 #endif
1084 frame_binding_(this), 1081 frame_binding_(this),
1082 has_accessed_initial_document_(false),
1085 weak_factory_(this) { 1083 weak_factory_(this) {
1086 // We don't have a shell::Connection at this point, so use nullptr. 1084 // We don't have a shell::Connection at this point, so use nullptr.
1087 // TODO(beng): We should fix this, so we can apply policy about which 1085 // TODO(beng): We should fix this, so we can apply policy about which
1088 // interfaces get exposed. 1086 // interfaces get exposed.
1089 interface_registry_.reset(new shell::InterfaceRegistry); 1087 interface_registry_.reset(new shell::InterfaceRegistry);
1090 shell::mojom::InterfaceProviderPtr remote_interfaces; 1088 shell::mojom::InterfaceProviderPtr remote_interfaces;
1091 pending_remote_interface_provider_request_ = GetProxy(&remote_interfaces); 1089 pending_remote_interface_provider_request_ = GetProxy(&remote_interfaces);
1092 remote_interfaces_.reset(new shell::InterfaceProvider); 1090 remote_interfaces_.reset(new shell::InterfaceProvider);
1093 remote_interfaces_->Bind(std::move(remote_interfaces)); 1091 remote_interfaces_->Bind(std::move(remote_interfaces));
1094 blink_interface_provider_.reset(new BlinkInterfaceProviderImpl( 1092 blink_interface_provider_.reset(new BlinkInterfaceProviderImpl(
(...skipping 1638 matching lines...) Expand 10 before | Expand all | Expand 10 after
2733 if (!provider->context()) { 2731 if (!provider->context()) {
2734 // The context can be null when the frame is sandboxed. 2732 // The context can be null when the frame is sandboxed.
2735 return nullptr; 2733 return nullptr;
2736 } 2734 }
2737 return new WebServiceWorkerProviderImpl( 2735 return new WebServiceWorkerProviderImpl(
2738 ChildThreadImpl::current()->thread_safe_sender(), 2736 ChildThreadImpl::current()->thread_safe_sender(),
2739 provider->context()); 2737 provider->context());
2740 } 2738 }
2741 2739
2742 void RenderFrameImpl::didAccessInitialDocument() { 2740 void RenderFrameImpl::didAccessInitialDocument() {
2741 DCHECK(!frame_->parent());
2743 // NOTE: Do not call back into JavaScript here, since this call is made from a 2742 // NOTE: Do not call back into JavaScript here, since this call is made from a
2744 // V8 security check. 2743 // V8 security check.
2745 2744
2746 // If the request hasn't yet committed, notify the browser process that it is 2745 // If the request hasn't yet committed, notify the browser process that it is
2747 // no longer safe to show the pending URL of the main frame, since a URL spoof 2746 // no longer safe to show the pending URL of the main frame, since a URL spoof
2748 // is now possible. (If the request has committed, the browser already knows.) 2747 // is now possible. (If the request has committed, the browser already knows.)
2749 if (!frame_->parent()) { 2748 if (!has_accessed_initial_document_) {
2750 DocumentState* document_state = 2749 DocumentState* document_state =
2751 DocumentState::FromDataSource(frame_->dataSource()); 2750 DocumentState::FromDataSource(frame_->dataSource());
2752 NavigationStateImpl* navigation_state = 2751 NavigationStateImpl* navigation_state =
2753 static_cast<NavigationStateImpl*>(document_state->navigation_state()); 2752 static_cast<NavigationStateImpl*>(document_state->navigation_state());
2754 2753
2755 if (!navigation_state->request_committed()) { 2754 if (!navigation_state->request_committed()) {
2756 Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_)); 2755 Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_));
2757 } 2756 }
2758 } 2757 }
2758
2759 has_accessed_initial_document_ = true;
2759 } 2760 }
2760 2761
2761 blink::WebFrame* RenderFrameImpl::createChildFrame( 2762 blink::WebFrame* RenderFrameImpl::createChildFrame(
2762 blink::WebLocalFrame* parent, 2763 blink::WebLocalFrame* parent,
2763 blink::WebTreeScopeType scope, 2764 blink::WebTreeScopeType scope,
2764 const blink::WebString& name, 2765 const blink::WebString& name,
2765 const blink::WebString& unique_name, 2766 const blink::WebString& unique_name,
2766 blink::WebSandboxFlags sandbox_flags, 2767 blink::WebSandboxFlags sandbox_flags,
2767 const blink::WebFrameOwnerProperties& frame_owner_properties) { 2768 const blink::WebFrameOwnerProperties& frame_owner_properties) {
2768 // Synchronously notify the browser of a child frame creation to get the 2769 // Synchronously notify the browser of a child frame creation to get the
(...skipping 2273 matching lines...) Expand 10 before | Expand all | Expand 10 after
5042 info.navigationType == blink::WebNavigationTypeOther; 5043 info.navigationType == blink::WebNavigationTypeOther;
5043 5044
5044 if (is_fork) { 5045 if (is_fork) {
5045 // Open the URL via the browser, not via WebKit. 5046 // Open the URL via the browser, not via WebKit.
5046 OpenURL(url, IsHttpPost(info.urlRequest), 5047 OpenURL(url, IsHttpPost(info.urlRequest),
5047 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(), 5048 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(),
5048 info.defaultPolicy, info.replacesCurrentHistoryItem, false); 5049 info.defaultPolicy, info.replacesCurrentHistoryItem, false);
5049 return blink::WebNavigationPolicyIgnore; 5050 return blink::WebNavigationPolicyIgnore;
5050 } 5051 }
5051 5052
5052 // Execute the BeforeUnload event. If asked not to proceed or the frame is 5053 bool should_dispatch_before_unload =
5053 // destroyed, ignore the navigation. There is no need to execute the 5054 info.defaultPolicy == blink::WebNavigationPolicyCurrentTab &&
5054 // BeforeUnload event during a redirect, since it was already executed at the 5055 // There is no need to execute the BeforeUnload event during a redirect,
5055 // start of the navigation. 5056 // since it was already executed at the start of the navigation.
5056 // PlzNavigate: this is not executed when commiting the navigation. 5057 !is_redirect &&
5057 if (info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && 5058 // PlzNavigate: this should not be executed when commiting the navigation.
5058 !is_redirect && (!IsBrowserSideNavigationEnabled() || 5059 (!IsBrowserSideNavigationEnabled() ||
5059 info.urlRequest.checkForBrowserSideNavigation())) { 5060 info.urlRequest.checkForBrowserSideNavigation()) &&
5061 // No need to dispatch beforeunload if the frame has not committed a
5062 // navigation and contains an empty initial document.
5063 (has_accessed_initial_document_ || !current_history_item_.isNull());
5064
5065 if (should_dispatch_before_unload) {
5066 // Execute the BeforeUnload event. If asked not to proceed or the frame is
5067 // destroyed, ignore the navigation.
5060 // Keep a WeakPtr to this RenderFrameHost to detect if executing the 5068 // Keep a WeakPtr to this RenderFrameHost to detect if executing the
5061 // BeforeUnload event destriyed this frame. 5069 // BeforeUnload event destriyed this frame.
5062 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); 5070 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
5063 5071
5064 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == 5072 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType ==
5065 blink::WebNavigationTypeReload) || 5073 blink::WebNavigationTypeReload) ||
5066 !weak_self) { 5074 !weak_self) {
5067 return blink::WebNavigationPolicyIgnore; 5075 return blink::WebNavigationPolicyIgnore;
5068 } 5076 }
5077
5078 // |navigation_start| must be recorded immediately after dispatching the
5079 // beforeunload event.
5080 if (pending_navigation_params_) {
5081 pending_navigation_params_->common_params.navigation_start =
5082 base::TimeTicks::Now();
5083 }
5069 } 5084 }
5070 5085
5071 // PlzNavigate: if the navigation is not synchronous, send it to the browser. 5086 // PlzNavigate: if the navigation is not synchronous, send it to the browser.
5072 // This includes navigations with no request being sent to the network stack. 5087 // This includes navigations with no request being sent to the network stack.
5073 if (IsBrowserSideNavigationEnabled() && 5088 if (IsBrowserSideNavigationEnabled() &&
5074 info.urlRequest.checkForBrowserSideNavigation() && 5089 info.urlRequest.checkForBrowserSideNavigation() &&
5075 ShouldMakeNetworkRequestForURL(url)) { 5090 ShouldMakeNetworkRequestForURL(url)) {
5076 BeginNavigation(info); 5091 BeginNavigation(info);
5077 return blink::WebNavigationPolicyHandledByClient; 5092 return blink::WebNavigationPolicyHandledByClient;
5078 } 5093 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
5415 } 5430 }
5416 5431
5417 // If the navigation is for "view source", the WebLocalFrame needs to be put 5432 // If the navigation is for "view source", the WebLocalFrame needs to be put
5418 // in a special mode. 5433 // in a special mode.
5419 if (request_params.is_view_source) 5434 if (request_params.is_view_source)
5420 frame_->enableViewSourceMode(true); 5435 frame_->enableViewSourceMode(true);
5421 5436
5422 pending_navigation_params_.reset( 5437 pending_navigation_params_.reset(
5423 new NavigationParams(common_params, start_params, request_params)); 5438 new NavigationParams(common_params, start_params, request_params));
5424 5439
5425 // Unless the load is a WebFrameLoadType::Standard, this should remain 5440 // Sanitize navigation start and store in |pending_navigation_params_|.
5426 // uninitialized. It will be updated when the load type is determined to be 5441 // It will be picked up in UpdateNavigationState.
5427 // Standard, or after the previous document's unload handler has been
5428 // triggered. This occurs in UpdateNavigationState.
5429 // TODO(csharrison) See if we can always use the browser timestamp.
5430 pending_navigation_params_->common_params.navigation_start = 5442 pending_navigation_params_->common_params.navigation_start =
5431 base::TimeTicks(); 5443 SanitizeNavigationTiming(common_params.navigation_start,
5444 renderer_navigation_start);
5432 5445
5433 // Create parameters for a standard navigation, indicating whether it should 5446 // Create parameters for a standard navigation, indicating whether it should
5434 // replace the current NavigationEntry. 5447 // replace the current NavigationEntry.
5435 blink::WebFrameLoadType load_type = 5448 blink::WebFrameLoadType load_type =
5436 common_params.should_replace_current_entry 5449 common_params.should_replace_current_entry
5437 ? blink::WebFrameLoadType::ReplaceCurrentItem 5450 ? blink::WebFrameLoadType::ReplaceCurrentItem
5438 : blink::WebFrameLoadType::Standard; 5451 : blink::WebFrameLoadType::Standard;
5439 blink::WebHistoryLoadType history_load_type = 5452 blink::WebHistoryLoadType history_load_type =
5440 blink::WebHistoryDifferentDocumentLoad; 5453 blink::WebHistoryDifferentDocumentLoad;
5441 bool should_load_request = false; 5454 bool should_load_request = false;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
5583 // TODO(creis): This is known to be failing in UseSubframeNavigationEntries 5596 // TODO(creis): This is known to be failing in UseSubframeNavigationEntries
5584 // in https://crbug.com/568703, when the PageState on a FrameNavigationEntry 5597 // in https://crbug.com/568703, when the PageState on a FrameNavigationEntry
5585 // is unexpectedly empty. Until the cause is found, keep this as a DCHECK 5598 // is unexpectedly empty. Until the cause is found, keep this as a DCHECK
5586 // and load the URL without PageState. 5599 // and load the URL without PageState.
5587 DCHECK_EQ(request_params.page_id, -1); 5600 DCHECK_EQ(request_params.page_id, -1);
5588 5601
5589 should_load_request = true; 5602 should_load_request = true;
5590 } 5603 }
5591 5604
5592 if (should_load_request) { 5605 if (should_load_request) {
5593 // Sanitize navigation start now that we know the load_type.
5594 pending_navigation_params_->common_params.navigation_start =
5595 SanitizeNavigationTiming(load_type, common_params.navigation_start,
5596 renderer_navigation_start);
5597
5598 // PlzNavigate: check if the navigation being committed originated as a 5606 // PlzNavigate: check if the navigation being committed originated as a
5599 // client redirect. 5607 // client redirect.
5600 bool is_client_redirect = 5608 bool is_client_redirect =
5601 browser_side_navigation 5609 browser_side_navigation
5602 ? !!(common_params.transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) 5610 ? !!(common_params.transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT)
5603 : false; 5611 : false;
5604 5612
5605 // Perform a navigation to a data url if needed. 5613 // Perform a navigation to a data url if needed.
5606 // Note: the base URL might be invalid, so also check the data URL string. 5614 // Note: the base URL might be invalid, so also check the data URL string.
5607 bool should_load_data_url = !common_params.base_url_for_data_url.is_empty(); 5615 bool should_load_data_url = !common_params.base_url_for_data_url.is_empty();
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
6035 // If this was a browser-initiated navigation, then there could be pending 6043 // If this was a browser-initiated navigation, then there could be pending
6036 // navigation params, so use them. Otherwise, just reset the document state 6044 // navigation params, so use them. Otherwise, just reset the document state
6037 // here, since if pending navigation params exist they are for some other 6045 // here, since if pending navigation params exist they are for some other
6038 // navigation <https://crbug.com/597239>. 6046 // navigation <https://crbug.com/597239>.
6039 if (!pending_navigation_params_ || content_initiated) { 6047 if (!pending_navigation_params_ || content_initiated) {
6040 document_state->set_navigation_state( 6048 document_state->set_navigation_state(
6041 NavigationStateImpl::CreateContentInitiated()); 6049 NavigationStateImpl::CreateContentInitiated());
6042 return; 6050 return;
6043 } 6051 }
6044 6052
6045 // If this is a browser-initiated load that doesn't override 6053 DCHECK(!pending_navigation_params_->common_params.navigation_start.is_null());
6046 // navigation_start, set it here.
6047 if (pending_navigation_params_->common_params.navigation_start.is_null()) {
6048 pending_navigation_params_->common_params.navigation_start =
6049 base::TimeTicks::Now();
6050 }
6051 document_state->set_navigation_state(CreateNavigationStateFromPending()); 6054 document_state->set_navigation_state(CreateNavigationStateFromPending());
6052 6055
6053 // The |set_was_load_data_with_base_url_request| state should not change for 6056 // The |set_was_load_data_with_base_url_request| state should not change for
6054 // an in-page navigation, so skip updating it from the in-page navigation 6057 // an in-page navigation, so skip updating it from the in-page navigation
6055 // params in this case. 6058 // params in this case.
6056 if (!was_within_same_page) { 6059 if (!was_within_same_page) {
6057 const CommonNavigationParams& common_params = 6060 const CommonNavigationParams& common_params =
6058 pending_navigation_params_->common_params; 6061 pending_navigation_params_->common_params;
6059 bool load_data = !common_params.base_url_for_data_url.is_empty() && 6062 bool load_data = !common_params.base_url_for_data_url.is_empty() &&
6060 !common_params.history_url_for_data_url.is_empty() && 6063 !common_params.history_url_for_data_url.is_empty() &&
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
6331 // event target. Potentially a Pepper plugin will receive the event. 6334 // event target. Potentially a Pepper plugin will receive the event.
6332 // In order to tell whether a plugin gets the last mouse event and which it 6335 // In order to tell whether a plugin gets the last mouse event and which it
6333 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets 6336 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets
6334 // the event, it will notify us via DidReceiveMouseEvent() and set itself as 6337 // the event, it will notify us via DidReceiveMouseEvent() and set itself as
6335 // |pepper_last_mouse_event_target_|. 6338 // |pepper_last_mouse_event_target_|.
6336 pepper_last_mouse_event_target_ = nullptr; 6339 pepper_last_mouse_event_target_ = nullptr;
6337 #endif 6340 #endif
6338 } 6341 }
6339 6342
6340 } // namespace content 6343 } // 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