| 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_->hasAccessedInitialDocument() || !current_history_item_.isNull()); |
| 5051 |
| 5052 if (should_dispatch_before_unload) { |
| 5053 // Execute the BeforeUnload event. If asked not to proceed or the frame is |
| 5054 // destroyed, ignore the navigation. |
| 5051 // Keep a WeakPtr to this RenderFrameHost to detect if executing the | 5055 // Keep a WeakPtr to this RenderFrameHost to detect if executing the |
| 5052 // BeforeUnload event destriyed this frame. | 5056 // BeforeUnload event destriyed this frame. |
| 5053 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); | 5057 base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); |
| 5054 | 5058 |
| 5055 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == | 5059 if (!frame_->dispatchBeforeUnloadEvent(info.navigationType == |
| 5056 blink::WebNavigationTypeReload) || | 5060 blink::WebNavigationTypeReload) || |
| 5057 !weak_self) { | 5061 !weak_self) { |
| 5058 return blink::WebNavigationPolicyIgnore; | 5062 return blink::WebNavigationPolicyIgnore; |
| 5059 } | 5063 } |
| 5064 |
| 5065 // |navigation_start| must be recorded immediately after dispatching the |
| 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 |