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 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |