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