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

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: Address comments. Created 4 years, 4 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
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 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 // Sanitizes the navigation_start timestamp for browser-initiated navigations, 571 // Sanitizes the navigation_start timestamp for browser-initiated navigations,
572 // where the browser possibly has a better notion of start time than the 572 // where the browser possibly has a better notion of start time than the
573 // renderer. In the case of cross-process navigations, this carries over the 573 // renderer. In the case of cross-process navigations, this carries over the
574 // time of finishing the onbeforeunload handler of the previous page. 574 // time of finishing the onbeforeunload handler of the previous page.
575 // TimeTicks is sometimes not monotonic across processes, and because 575 // TimeTicks is sometimes not monotonic across processes, and because
576 // |browser_navigation_start| is likely before this process existed, 576 // |browser_navigation_start| is likely before this process existed,
577 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by 577 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by
578 // clamping it to renderer_navigation_start, initialized earlier in the call 578 // clamping it to renderer_navigation_start, initialized earlier in the call
579 // stack. 579 // stack.
580 base::TimeTicks SanitizeNavigationTiming( 580 base::TimeTicks SanitizeNavigationTiming(
581 blink::WebFrameLoadType load_type,
582 const base::TimeTicks& browser_navigation_start, 581 const base::TimeTicks& browser_navigation_start,
583 const base::TimeTicks& renderer_navigation_start) { 582 const base::TimeTicks& renderer_navigation_start) {
584 if (load_type != blink::WebFrameLoadType::Standard)
585 return base::TimeTicks();
586 DCHECK(!browser_navigation_start.is_null()); 583 DCHECK(!browser_navigation_start.is_null());
587 base::TimeTicks navigation_start = 584 base::TimeTicks navigation_start =
588 std::min(browser_navigation_start, renderer_navigation_start); 585 std::min(browser_navigation_start, renderer_navigation_start);
589 base::TimeDelta difference = 586 base::TimeDelta difference =
590 renderer_navigation_start - browser_navigation_start; 587 renderer_navigation_start - browser_navigation_start;
591 if (difference > base::TimeDelta()) { 588 if (difference > base::TimeDelta()) {
592 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive", 589 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive",
593 difference); 590 difference);
594 } else { 591 } else {
595 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative", 592 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative",
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 effective_connection_type_( 1108 effective_connection_type_(
1112 blink::WebEffectiveConnectionType::TypeUnknown), 1109 blink::WebEffectiveConnectionType::TypeUnknown),
1113 is_pasting_(false), 1110 is_pasting_(false),
1114 suppress_further_dialogs_(false), 1111 suppress_further_dialogs_(false),
1115 blame_context_(nullptr), 1112 blame_context_(nullptr),
1116 #if defined(ENABLE_PLUGINS) 1113 #if defined(ENABLE_PLUGINS)
1117 focused_pepper_plugin_(nullptr), 1114 focused_pepper_plugin_(nullptr),
1118 pepper_last_mouse_event_target_(nullptr), 1115 pepper_last_mouse_event_target_(nullptr),
1119 #endif 1116 #endif
1120 frame_binding_(this), 1117 frame_binding_(this),
1118 has_accessed_initial_document_(false),
1121 weak_factory_(this) { 1119 weak_factory_(this) {
1122 // We don't have a shell::Connection at this point, so use nullptr. 1120 // We don't have a shell::Connection at this point, so use nullptr.
1123 // TODO(beng): We should fix this, so we can apply policy about which 1121 // TODO(beng): We should fix this, so we can apply policy about which
1124 // interfaces get exposed. 1122 // interfaces get exposed.
1125 interface_registry_.reset(new shell::InterfaceRegistry(nullptr)); 1123 interface_registry_.reset(new shell::InterfaceRegistry(nullptr));
1126 shell::mojom::InterfaceProviderPtr remote_interfaces; 1124 shell::mojom::InterfaceProviderPtr remote_interfaces;
1127 pending_remote_interface_provider_request_ = GetProxy(&remote_interfaces); 1125 pending_remote_interface_provider_request_ = GetProxy(&remote_interfaces);
1128 remote_interfaces_.reset(new shell::InterfaceProvider); 1126 remote_interfaces_.reset(new shell::InterfaceProvider);
1129 remote_interfaces_->Bind(std::move(remote_interfaces)); 1127 remote_interfaces_->Bind(std::move(remote_interfaces));
1130 blink_interface_provider_.reset(new BlinkInterfaceProviderImpl( 1128 blink_interface_provider_.reset(new BlinkInterfaceProviderImpl(
(...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after
2765 if (!provider->context()) { 2763 if (!provider->context()) {
2766 // The context can be null when the frame is sandboxed. 2764 // The context can be null when the frame is sandboxed.
2767 return nullptr; 2765 return nullptr;
2768 } 2766 }
2769 return new WebServiceWorkerProviderImpl( 2767 return new WebServiceWorkerProviderImpl(
2770 ChildThreadImpl::current()->thread_safe_sender(), 2768 ChildThreadImpl::current()->thread_safe_sender(),
2771 provider->context()); 2769 provider->context());
2772 } 2770 }
2773 2771
2774 void RenderFrameImpl::didAccessInitialDocument() { 2772 void RenderFrameImpl::didAccessInitialDocument() {
2773 DCHECK(!frame_->parent());
2775 // NOTE: Do not call back into JavaScript here, since this call is made from a 2774 // NOTE: Do not call back into JavaScript here, since this call is made from a
2776 // V8 security check. 2775 // V8 security check.
2777 2776
2778 // If the request hasn't yet committed, notify the browser process that it is 2777 // If the request hasn't yet committed, notify the browser process that it is
2779 // no longer safe to show the pending URL of the main frame, since a URL spoof 2778 // no longer safe to show the pending URL of the main frame, since a URL spoof
2780 // is now possible. (If the request has committed, the browser already knows.) 2779 // is now possible. (If the request has committed, the browser already knows.)
2781 if (!frame_->parent()) { 2780 if (!has_accessed_initial_document_) {
2782 DocumentState* document_state = 2781 DocumentState* document_state =
2783 DocumentState::FromDataSource(frame_->dataSource()); 2782 DocumentState::FromDataSource(frame_->dataSource());
2784 NavigationStateImpl* navigation_state = 2783 NavigationStateImpl* navigation_state =
2785 static_cast<NavigationStateImpl*>(document_state->navigation_state()); 2784 static_cast<NavigationStateImpl*>(document_state->navigation_state());
2786 2785
2787 if (!navigation_state->request_committed()) { 2786 if (!navigation_state->request_committed()) {
2788 Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_)); 2787 Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_));
2789 } 2788 }
2790 } 2789 }
2790
2791 has_accessed_initial_document_ = true;
2791 } 2792 }
2792 2793
2793 blink::WebFrame* RenderFrameImpl::createChildFrame( 2794 blink::WebFrame* RenderFrameImpl::createChildFrame(
2794 blink::WebLocalFrame* parent, 2795 blink::WebLocalFrame* parent,
2795 blink::WebTreeScopeType scope, 2796 blink::WebTreeScopeType scope,
2796 const blink::WebString& name, 2797 const blink::WebString& name,
2797 const blink::WebString& unique_name, 2798 const blink::WebString& unique_name,
2798 blink::WebSandboxFlags sandbox_flags, 2799 blink::WebSandboxFlags sandbox_flags,
2799 const blink::WebFrameOwnerProperties& frame_owner_properties) { 2800 const blink::WebFrameOwnerProperties& frame_owner_properties) {
2800 // Synchronously notify the browser of a child frame creation to get the 2801 // Synchronously notify the browser of a child frame creation to get the
(...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after
5065 info.navigationType == blink::WebNavigationTypeOther; 5066 info.navigationType == blink::WebNavigationTypeOther;
5066 5067
5067 if (is_fork) { 5068 if (is_fork) {
5068 // Open the URL via the browser, not via WebKit. 5069 // Open the URL via the browser, not via WebKit.
5069 OpenURL(url, IsHttpPost(info.urlRequest), 5070 OpenURL(url, IsHttpPost(info.urlRequest),
5070 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(), 5071 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(),
5071 info.defaultPolicy, info.replacesCurrentHistoryItem, false); 5072 info.defaultPolicy, info.replacesCurrentHistoryItem, false);
5072 return blink::WebNavigationPolicyIgnore; 5073 return blink::WebNavigationPolicyIgnore;
5073 } 5074 }
5074 5075
5075 // Execute the BeforeUnload event. If asked not to proceed or the frame is 5076 bool should_dispatch_before_unload =
5076 // destroyed, ignore the navigation. There is no need to execute the 5077 info.defaultPolicy == blink::WebNavigationPolicyCurrentTab &&
5077 // BeforeUnload event during a redirect, since it was already executed at the 5078 // There is no need to execute the BeforeUnload event during a redirect,
5078 // start of the navigation. 5079 // since it was already executed at the start of the navigation.
5079 // PlzNavigate: this is not executed when commiting the navigation. 5080 !is_redirect &&
5080 if (info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && 5081 // PlzNavigate: this should not be executed when commiting the navigation.
5081 !is_redirect && (!IsBrowserSideNavigationEnabled() || 5082 (!IsBrowserSideNavigationEnabled() ||
5082 info.urlRequest.checkForBrowserSideNavigation())) { 5083 info.urlRequest.checkForBrowserSideNavigation()) &&
5084 // No need to dispatch beforeunload if the frame has not committed a
5085 // navigation and contains an empty initial document.
5086 (has_accessed_initial_document_ || !current_history_item_.isNull());
5087
5088 if (should_dispatch_before_unload) {
5089 // Execute the BeforeUnload event. If asked not to proceed or the frame is
5090 // destroyed, ignore the navigation.
5083 // Keep a WeakPtr to this RenderFrameHost to detect if executing the 5091 // Keep a WeakPtr to this RenderFrameHost to detect if executing the
5084 // BeforeUnload event destriyed this frame. 5092 // BeforeUnload event destriyed this frame.
5085 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); 5093 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
5086 5094
5087 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == 5095 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType ==
5088 blink::WebNavigationTypeReload) || 5096 blink::WebNavigationTypeReload) ||
5089 !weak_self) { 5097 !weak_self) {
5090 return blink::WebNavigationPolicyIgnore; 5098 return blink::WebNavigationPolicyIgnore;
5091 } 5099 }
5100
5101 // |navigation_start| must be recorded immediately after dispatching the
5102 // beforeunload event.
5103 if (pending_navigation_params_) {
5104 pending_navigation_params_->common_params.navigation_start =
5105 base::TimeTicks::Now();
5106 }
5092 } 5107 }
5093 5108
5094 // PlzNavigate: if the navigation is not synchronous, send it to the browser. 5109 // PlzNavigate: if the navigation is not synchronous, send it to the browser.
5095 // This includes navigations with no request being sent to the network stack. 5110 // This includes navigations with no request being sent to the network stack.
5096 if (IsBrowserSideNavigationEnabled() && 5111 if (IsBrowserSideNavigationEnabled() &&
5097 info.urlRequest.checkForBrowserSideNavigation() && 5112 info.urlRequest.checkForBrowserSideNavigation() &&
5098 ShouldMakeNetworkRequestForURL(url)) { 5113 ShouldMakeNetworkRequestForURL(url)) {
5099 BeginNavigation(info); 5114 BeginNavigation(info);
5100 return blink::WebNavigationPolicyHandledByClient; 5115 return blink::WebNavigationPolicyHandledByClient;
5101 } 5116 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
5438 } 5453 }
5439 5454
5440 // If the navigation is for "view source", the WebLocalFrame needs to be put 5455 // If the navigation is for "view source", the WebLocalFrame needs to be put
5441 // in a special mode. 5456 // in a special mode.
5442 if (request_params.is_view_source) 5457 if (request_params.is_view_source)
5443 frame_->enableViewSourceMode(true); 5458 frame_->enableViewSourceMode(true);
5444 5459
5445 pending_navigation_params_.reset( 5460 pending_navigation_params_.reset(
5446 new NavigationParams(common_params, start_params, request_params)); 5461 new NavigationParams(common_params, start_params, request_params));
5447 5462
5448 // Unless the load is a WebFrameLoadType::Standard, this should remain 5463 // Sanitize navigation start and store in |pending_navigation_params_|.
5449 // uninitialized. It will be updated when the load type is determined to be 5464 // It will be picked up in UpdateNavigationState.
5450 // Standard, or after the previous document's unload handler has been
5451 // triggered. This occurs in UpdateNavigationState.
5452 // TODO(csharrison) See if we can always use the browser timestamp.
5453 pending_navigation_params_->common_params.navigation_start = 5465 pending_navigation_params_->common_params.navigation_start =
5454 base::TimeTicks(); 5466 SanitizeNavigationTiming(common_params.navigation_start,
5467 renderer_navigation_start);
5455 5468
5456 // Create parameters for a standard navigation, indicating whether it should 5469 // Create parameters for a standard navigation, indicating whether it should
5457 // replace the current NavigationEntry. 5470 // replace the current NavigationEntry.
5458 blink::WebFrameLoadType load_type = 5471 blink::WebFrameLoadType load_type =
5459 common_params.should_replace_current_entry 5472 common_params.should_replace_current_entry
5460 ? blink::WebFrameLoadType::ReplaceCurrentItem 5473 ? blink::WebFrameLoadType::ReplaceCurrentItem
5461 : blink::WebFrameLoadType::Standard; 5474 : blink::WebFrameLoadType::Standard;
5462 blink::WebHistoryLoadType history_load_type = 5475 blink::WebHistoryLoadType history_load_type =
5463 blink::WebHistoryDifferentDocumentLoad; 5476 blink::WebHistoryDifferentDocumentLoad;
5464 bool should_load_request = false; 5477 bool should_load_request = false;
(...skipping 118 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 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
6034 // If this was a browser-initiated navigation, then there could be pending 6042 // If this was a browser-initiated navigation, then there could be pending
6035 // navigation params, so use them. Otherwise, just reset the document state 6043 // navigation params, so use them. Otherwise, just reset the document state
6036 // here, since if pending navigation params exist they are for some other 6044 // here, since if pending navigation params exist they are for some other
6037 // navigation <https://crbug.com/597239>. 6045 // navigation <https://crbug.com/597239>.
6038 if (!pending_navigation_params_ || content_initiated) { 6046 if (!pending_navigation_params_ || content_initiated) {
6039 document_state->set_navigation_state( 6047 document_state->set_navigation_state(
6040 NavigationStateImpl::CreateContentInitiated()); 6048 NavigationStateImpl::CreateContentInitiated());
6041 return; 6049 return;
6042 } 6050 }
6043 6051
6044 // If this is a browser-initiated load that doesn't override 6052 DCHECK(!pending_navigation_params_->common_params.navigation_start.is_null());
6045 // navigation_start, set it here.
6046 if (pending_navigation_params_->common_params.navigation_start.is_null()) {
6047 pending_navigation_params_->common_params.navigation_start =
6048 base::TimeTicks::Now();
6049 }
6050 document_state->set_navigation_state(CreateNavigationStateFromPending()); 6053 document_state->set_navigation_state(CreateNavigationStateFromPending());
6051 6054
6052 // The |set_was_load_data_with_base_url_request| state should not change for 6055 // The |set_was_load_data_with_base_url_request| state should not change for
6053 // an in-page navigation, so skip updating it from the in-page navigation 6056 // an in-page navigation, so skip updating it from the in-page navigation
6054 // params in this case. 6057 // params in this case.
6055 if (!was_within_same_page) { 6058 if (!was_within_same_page) {
6056 const CommonNavigationParams& common_params = 6059 const CommonNavigationParams& common_params =
6057 pending_navigation_params_->common_params; 6060 pending_navigation_params_->common_params;
6058 bool load_data = !common_params.base_url_for_data_url.is_empty() && 6061 bool load_data = !common_params.base_url_for_data_url.is_empty() &&
6059 !common_params.history_url_for_data_url.is_empty() && 6062 !common_params.history_url_for_data_url.is_empty() &&
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
6330 // event target. Potentially a Pepper plugin will receive the event. 6333 // event target. Potentially a Pepper plugin will receive the event.
6331 // In order to tell whether a plugin gets the last mouse event and which it 6334 // In order to tell whether a plugin gets the last mouse event and which it
6332 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets 6335 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets
6333 // the event, it will notify us via DidReceiveMouseEvent() and set itself as 6336 // the event, it will notify us via DidReceiveMouseEvent() and set itself as
6334 // |pepper_last_mouse_event_target_|. 6337 // |pepper_last_mouse_event_target_|.
6335 pepper_last_mouse_event_target_ = nullptr; 6338 pepper_last_mouse_event_target_ = nullptr;
6336 #endif 6339 #endif
6337 } 6340 }
6338 6341
6339 } // namespace content 6342 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698