OLD | NEW |
---|---|
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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 // Sanitizes the navigation_start timestamp for browser-initiated navigations, | 558 // Sanitizes the navigation_start timestamp for browser-initiated navigations, |
559 // where the browser possibly has a better notion of start time than the | 559 // where the browser possibly has a better notion of start time than the |
560 // renderer. In the case of cross-process navigations, this carries over the | 560 // renderer. In the case of cross-process navigations, this carries over the |
561 // time of finishing the onbeforeunload handler of the previous page. | 561 // time of finishing the onbeforeunload handler of the previous page. |
562 // TimeTicks is sometimes not monotonic across processes, and because | 562 // TimeTicks is sometimes not monotonic across processes, and because |
563 // |browser_navigation_start| is likely before this process existed, | 563 // |browser_navigation_start| is likely before this process existed, |
564 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by | 564 // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by |
565 // clamping it to renderer_navigation_start, initialized earlier in the call | 565 // clamping it to renderer_navigation_start, initialized earlier in the call |
566 // stack. | 566 // stack. |
567 base::TimeTicks SanitizeNavigationTiming( | 567 base::TimeTicks SanitizeNavigationTiming( |
568 blink::WebFrameLoadType load_type, | |
569 const base::TimeTicks& browser_navigation_start, | 568 const base::TimeTicks& browser_navigation_start, |
570 const base::TimeTicks& renderer_navigation_start) { | 569 const base::TimeTicks& renderer_navigation_start) { |
571 if (load_type != blink::WebFrameLoadType::Standard) | |
572 return base::TimeTicks(); | |
573 DCHECK(!browser_navigation_start.is_null()); | 570 DCHECK(!browser_navigation_start.is_null()); |
574 base::TimeTicks navigation_start = | 571 base::TimeTicks navigation_start = |
575 std::min(browser_navigation_start, renderer_navigation_start); | 572 std::min(browser_navigation_start, renderer_navigation_start); |
576 base::TimeDelta difference = | 573 base::TimeDelta difference = |
577 renderer_navigation_start - browser_navigation_start; | 574 renderer_navigation_start - browser_navigation_start; |
578 if (difference > base::TimeDelta()) { | 575 if (difference > base::TimeDelta()) { |
579 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive", | 576 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Positive", |
580 difference); | 577 difference); |
581 } else { | 578 } else { |
582 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative", | 579 UMA_HISTOGRAM_TIMES("Navigation.Start.RendererBrowserDifference.Negative", |
(...skipping 4450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5033 info.navigationType == blink::WebNavigationTypeOther; | 5030 info.navigationType == blink::WebNavigationTypeOther; |
5034 | 5031 |
5035 if (is_fork) { | 5032 if (is_fork) { |
5036 // Open the URL via the browser, not via WebKit. | 5033 // Open the URL via the browser, not via WebKit. |
5037 OpenURL(url, IsHttpPost(info.urlRequest), | 5034 OpenURL(url, IsHttpPost(info.urlRequest), |
5038 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(), | 5035 GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(), |
5039 info.defaultPolicy, info.replacesCurrentHistoryItem, false); | 5036 info.defaultPolicy, info.replacesCurrentHistoryItem, false); |
5040 return blink::WebNavigationPolicyIgnore; | 5037 return blink::WebNavigationPolicyIgnore; |
5041 } | 5038 } |
5042 | 5039 |
5043 // Execute the BeforeUnload event. If asked not to proceed or the frame is | 5040 bool should_dispatch_before_unload = |
5044 // destroyed, ignore the navigation. There is no need to execute the | 5041 info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && |
5045 // BeforeUnload event during a redirect, since it was already executed at the | 5042 // There is no need to execute the BeforeUnload event during a redirect, |
5046 // start of the navigation. | 5043 // since it was already executed at the start of the navigation. |
5047 // PlzNavigate: this is not executed when commiting the navigation. | 5044 !is_redirect && |
5048 if (info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && | 5045 // PlzNavigate: this should not be executed when commiting the navigation. |
5049 !is_redirect && (!IsBrowserSideNavigationEnabled() || | 5046 (!IsBrowserSideNavigationEnabled() || |
5050 info.urlRequest.checkForBrowserSideNavigation())) { | 5047 info.urlRequest.checkForBrowserSideNavigation()) && |
5048 // No need to dispatch beforeunload if the frame has not committed a | |
5049 // navigation and contains an empty initial document. | |
5050 (frame_->getDidAccessInitialDocument() || | |
5051 !current_history_item_.isNull()); | |
5052 | |
5053 if (should_dispatch_before_unload) { | |
5054 // Execute the BeforeUnload event. If asked not to proceed or the frame is | |
5055 // destroyed, ignore the navigation. | |
5051 // Keep a WeakPtr to this RenderFrameHost to detect if executing the | 5056 // Keep a WeakPtr to this RenderFrameHost to detect if executing the |
5052 // BeforeUnload event destriyed this frame. | 5057 // BeforeUnload event destriyed this frame. |
5053 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); | 5058 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); |
5054 | 5059 |
5055 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == | 5060 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == |
5056 blink::WebNavigationTypeReload) || | 5061 blink::WebNavigationTypeReload) || |
5057 !weak_self) { | 5062 !weak_self) { |
5058 return blink::WebNavigationPolicyIgnore; | 5063 return blink::WebNavigationPolicyIgnore; |
5059 } | 5064 } |
5065 // navigation_start must be recorded immediately after dispatching the | |
clamy
2016/07/21 11:52:44
nit: blank line above.
s/navigation_start/|navigat
Alexander Semashko
2016/07/21 14:00:22
Done.
| |
5066 // beforeunload event. | |
5067 if (pending_navigation_params_) { | |
5068 pending_navigation_params_->common_params.navigation_start = | |
5069 base::TimeTicks::Now(); | |
5070 } | |
5060 } | 5071 } |
5061 | 5072 |
5062 // PlzNavigate: if the navigation is not synchronous, send it to the browser. | 5073 // PlzNavigate: if the navigation is not synchronous, send it to the browser. |
5063 // This includes navigations with no request being sent to the network stack. | 5074 // This includes navigations with no request being sent to the network stack. |
5064 if (IsBrowserSideNavigationEnabled() && | 5075 if (IsBrowserSideNavigationEnabled() && |
5065 info.urlRequest.checkForBrowserSideNavigation() && | 5076 info.urlRequest.checkForBrowserSideNavigation() && |
5066 ShouldMakeNetworkRequestForURL(url)) { | 5077 ShouldMakeNetworkRequestForURL(url)) { |
5067 BeginNavigation(&info.urlRequest, info.replacesCurrentHistoryItem, | 5078 BeginNavigation(&info.urlRequest, info.replacesCurrentHistoryItem, |
5068 info.isClientRedirect); | 5079 info.isClientRedirect); |
5069 return blink::WebNavigationPolicyHandledByClient; | 5080 return blink::WebNavigationPolicyHandledByClient; |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5447 } | 5458 } |
5448 | 5459 |
5449 // If the navigation is for "view source", the WebLocalFrame needs to be put | 5460 // If the navigation is for "view source", the WebLocalFrame needs to be put |
5450 // in a special mode. | 5461 // in a special mode. |
5451 if (request_params.is_view_source) | 5462 if (request_params.is_view_source) |
5452 frame_->enableViewSourceMode(true); | 5463 frame_->enableViewSourceMode(true); |
5453 | 5464 |
5454 pending_navigation_params_.reset( | 5465 pending_navigation_params_.reset( |
5455 new NavigationParams(common_params, start_params, request_params)); | 5466 new NavigationParams(common_params, start_params, request_params)); |
5456 | 5467 |
5457 // Unless the load is a WebFrameLoadType::Standard, this should remain | 5468 // Sanitize navigation start and store in |pending_navigation_params_|. |
5458 // uninitialized. It will be updated when the load type is determined to be | 5469 // It will be picked up in UpdateNavigationState. |
5459 // Standard, or after the previous document's unload handler has been | |
5460 // triggered. This occurs in UpdateNavigationState. | |
5461 // TODO(csharrison) See if we can always use the browser timestamp. | |
5462 pending_navigation_params_->common_params.navigation_start = | 5470 pending_navigation_params_->common_params.navigation_start = |
5463 base::TimeTicks(); | 5471 SanitizeNavigationTiming(common_params.navigation_start, |
5472 renderer_navigation_start); | |
5464 | 5473 |
5465 // Create parameters for a standard navigation, indicating whether it should | 5474 // Create parameters for a standard navigation, indicating whether it should |
5466 // replace the current NavigationEntry. | 5475 // replace the current NavigationEntry. |
5467 blink::WebFrameLoadType load_type = | 5476 blink::WebFrameLoadType load_type = |
5468 common_params.should_replace_current_entry | 5477 common_params.should_replace_current_entry |
5469 ? blink::WebFrameLoadType::ReplaceCurrentItem | 5478 ? blink::WebFrameLoadType::ReplaceCurrentItem |
5470 : blink::WebFrameLoadType::Standard; | 5479 : blink::WebFrameLoadType::Standard; |
5471 blink::WebHistoryLoadType history_load_type = | 5480 blink::WebHistoryLoadType history_load_type = |
5472 blink::WebHistoryDifferentDocumentLoad; | 5481 blink::WebHistoryDifferentDocumentLoad; |
5473 bool should_load_request = false; | 5482 bool should_load_request = false; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5576 GetWebHTTPBodyForRequestBody(common_params.post_data)); | 5585 GetWebHTTPBodyForRequestBody(common_params.post_data)); |
5577 } | 5586 } |
5578 | 5587 |
5579 // A session history navigation should have been accompanied by state. | 5588 // A session history navigation should have been accompanied by state. |
5580 CHECK_EQ(request_params.page_id, -1); | 5589 CHECK_EQ(request_params.page_id, -1); |
5581 | 5590 |
5582 should_load_request = true; | 5591 should_load_request = true; |
5583 } | 5592 } |
5584 | 5593 |
5585 if (should_load_request) { | 5594 if (should_load_request) { |
5586 // Sanitize navigation start now that we know the load_type. | |
5587 pending_navigation_params_->common_params.navigation_start = | |
5588 SanitizeNavigationTiming(load_type, common_params.navigation_start, | |
5589 renderer_navigation_start); | |
5590 | |
5591 // PlzNavigate: check if the navigation being committed originated as a | 5595 // PlzNavigate: check if the navigation being committed originated as a |
5592 // client redirect. | 5596 // client redirect. |
5593 bool is_client_redirect = | 5597 bool is_client_redirect = |
5594 browser_side_navigation | 5598 browser_side_navigation |
5595 ? !!(common_params.transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) | 5599 ? !!(common_params.transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) |
5596 : false; | 5600 : false; |
5597 | 5601 |
5598 // Perform a navigation to a data url if needed. | 5602 // Perform a navigation to a data url if needed. |
5599 // Note: the base URL might be invalid, so also check the data URL string. | 5603 // Note: the base URL might be invalid, so also check the data URL string. |
5600 bool should_load_data_url = !common_params.base_url_for_data_url.is_empty(); | 5604 bool should_load_data_url = !common_params.base_url_for_data_url.is_empty(); |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6020 // If this was a browser-initiated navigation, then there could be pending | 6024 // If this was a browser-initiated navigation, then there could be pending |
6021 // navigation params, so use them. Otherwise, just reset the document state | 6025 // navigation params, so use them. Otherwise, just reset the document state |
6022 // here, since if pending navigation params exist they are for some other | 6026 // here, since if pending navigation params exist they are for some other |
6023 // navigation <https://crbug.com/597239>. | 6027 // navigation <https://crbug.com/597239>. |
6024 if (!pending_navigation_params_ || content_initiated) { | 6028 if (!pending_navigation_params_ || content_initiated) { |
6025 document_state->set_navigation_state( | 6029 document_state->set_navigation_state( |
6026 NavigationStateImpl::CreateContentInitiated()); | 6030 NavigationStateImpl::CreateContentInitiated()); |
6027 return; | 6031 return; |
6028 } | 6032 } |
6029 | 6033 |
6030 // If this is a browser-initiated load that doesn't override | 6034 DCHECK(!pending_navigation_params_->common_params.navigation_start.is_null()); |
6031 // navigation_start, set it here. | |
6032 if (pending_navigation_params_->common_params.navigation_start.is_null()) { | |
6033 pending_navigation_params_->common_params.navigation_start = | |
6034 base::TimeTicks::Now(); | |
6035 } | |
6036 document_state->set_navigation_state(CreateNavigationStateFromPending()); | 6035 document_state->set_navigation_state(CreateNavigationStateFromPending()); |
6037 | 6036 |
6038 // The |set_was_load_data_with_base_url_request| state should not change for | 6037 // The |set_was_load_data_with_base_url_request| state should not change for |
6039 // an in-page navigation, so skip updating it from the in-page navigation | 6038 // an in-page navigation, so skip updating it from the in-page navigation |
6040 // params in this case. | 6039 // params in this case. |
6041 if (!was_within_same_page) { | 6040 if (!was_within_same_page) { |
6042 const CommonNavigationParams& common_params = | 6041 const CommonNavigationParams& common_params = |
6043 pending_navigation_params_->common_params; | 6042 pending_navigation_params_->common_params; |
6044 bool load_data = !common_params.base_url_for_data_url.is_empty() && | 6043 bool load_data = !common_params.base_url_for_data_url.is_empty() && |
6045 !common_params.history_url_for_data_url.is_empty() && | 6044 !common_params.history_url_for_data_url.is_empty() && |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6328 // event target. Potentially a Pepper plugin will receive the event. | 6327 // event target. Potentially a Pepper plugin will receive the event. |
6329 // In order to tell whether a plugin gets the last mouse event and which it | 6328 // In order to tell whether a plugin gets the last mouse event and which it |
6330 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets | 6329 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets |
6331 // the event, it will notify us via DidReceiveMouseEvent() and set itself as | 6330 // the event, it will notify us via DidReceiveMouseEvent() and set itself as |
6332 // |pepper_last_mouse_event_target_|. | 6331 // |pepper_last_mouse_event_target_|. |
6333 pepper_last_mouse_event_target_ = nullptr; | 6332 pepper_last_mouse_event_target_ = nullptr; |
6334 #endif | 6333 #endif |
6335 } | 6334 } |
6336 | 6335 |
6337 } // namespace content | 6336 } // namespace content |
OLD | NEW |