Chromium Code Reviews| 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/browser/frame_host/render_frame_host_impl.h" | 5 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 if (!GetParent()) | 815 if (!GetParent()) |
| 816 delegate_->SwappedOut(this); | 816 delegate_->SwappedOut(this); |
| 817 } | 817 } |
| 818 | 818 |
| 819 void RenderFrameHostImpl::OnBeforeUnloadACK( | 819 void RenderFrameHostImpl::OnBeforeUnloadACK( |
| 820 bool proceed, | 820 bool proceed, |
| 821 const base::TimeTicks& renderer_before_unload_start_time, | 821 const base::TimeTicks& renderer_before_unload_start_time, |
| 822 const base::TimeTicks& renderer_before_unload_end_time) { | 822 const base::TimeTicks& renderer_before_unload_end_time) { |
| 823 TRACE_EVENT_ASYNC_END0( | 823 TRACE_EVENT_ASYNC_END0( |
| 824 "navigation", "RenderFrameHostImpl::BeforeUnload", this); | 824 "navigation", "RenderFrameHostImpl::BeforeUnload", this); |
| 825 // TODO(creis): Support beforeunload on subframes. For now just pretend that | |
| 826 // the handler ran and allowed the navigation to proceed. | |
| 827 if (GetParent()) { | |
| 828 is_waiting_for_beforeunload_ack_ = false; | |
| 829 frame_tree_node_->render_manager()->OnBeforeUnloadACK( | |
| 830 unload_ack_is_for_cross_site_transition_, proceed, | |
| 831 renderer_before_unload_end_time); | |
| 832 return; | |
| 833 } | |
| 834 | 825 |
| 835 render_view_host_->decrement_in_flight_event_count(); | 826 render_view_host_->decrement_in_flight_event_count(); |
| 836 render_view_host_->StopHangMonitorTimeout(); | 827 render_view_host_->StopHangMonitorTimeout(); |
| 837 // If this renderer navigated while the beforeunload request was in flight, we | 828 // If this renderer navigated while the beforeunload request was in flight, we |
| 838 // may have cleared this state in OnDidCommitProvisionalLoad, in which case we | 829 // may have cleared this state in OnDidCommitProvisionalLoad, in which case we |
| 839 // can ignore this message. | 830 // can ignore this message. |
| 840 // However renderer might also be swapped out but we still want to proceed | 831 // However renderer might also be swapped out but we still want to proceed |
| 841 // with navigation, otherwise it would block future navigations. This can | 832 // with navigation, otherwise it would block future navigations. This can |
| 842 // happen when pending cross-site navigation is canceled by a second one just | 833 // happen when pending cross-site navigation is canceled by a second one just |
| 843 // before OnDidCommitProvisionalLoad while current RVH is waiting for commit | 834 // before OnDidCommitProvisionalLoad while current RVH is waiting for commit |
| 844 // but second navigation is started from the beginning. | 835 // but second navigation is started from the beginning. |
| 845 if (!is_waiting_for_beforeunload_ack_) { | 836 if (!is_waiting_for_beforeunload_ack_) { |
| 846 return; | 837 return; |
| 847 } | 838 } |
| 848 | 839 |
| 849 is_waiting_for_beforeunload_ack_ = false; | 840 is_waiting_for_beforeunload_ack_ = false; |
| 850 | 841 |
| 851 base::TimeTicks before_unload_end_time; | 842 base::TimeTicks before_unload_end_time; |
| 852 if (!send_before_unload_start_time_.is_null() && | 843 if (!renderer_before_unload_start_time.is_null() && |
|
carlosk
2014/10/15 12:29:04
This wasn't really working anyway.
| |
| 853 !renderer_before_unload_start_time.is_null() && | |
| 854 !renderer_before_unload_end_time.is_null()) { | 844 !renderer_before_unload_end_time.is_null()) { |
| 855 // When passing TimeTicks across process boundaries, we need to compensate | 845 // When passing TimeTicks across process boundaries, we need to compensate |
| 856 // for any skew between the processes. Here we are converting the | 846 // for any skew between the processes. Here we are converting the |
| 857 // renderer's notion of before_unload_end_time to TimeTicks in the browser | 847 // renderer's notion of before_unload_end_time to TimeTicks in the browser |
| 858 // process. See comments in inter_process_time_ticks_converter.h for more. | 848 // process. See comments in inter_process_time_ticks_converter.h for more. |
| 849 base::TimeTicks receive_before_unload_ack_time = base::TimeTicks::Now(); | |
| 859 InterProcessTimeTicksConverter converter( | 850 InterProcessTimeTicksConverter converter( |
| 860 LocalTimeTicks::FromTimeTicks(send_before_unload_start_time_), | 851 LocalTimeTicks::FromTimeTicks(send_before_unload_start_time_), |
| 861 LocalTimeTicks::FromTimeTicks(base::TimeTicks::Now()), | 852 LocalTimeTicks::FromTimeTicks(receive_before_unload_ack_time), |
| 862 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_start_time), | 853 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_start_time), |
| 863 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time)); | 854 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time)); |
| 864 LocalTimeTicks browser_before_unload_end_time = | 855 LocalTimeTicks browser_before_unload_end_time = |
| 865 converter.ToLocalTimeTicks( | 856 converter.ToLocalTimeTicks( |
| 866 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time)); | 857 RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time)); |
| 867 before_unload_end_time = browser_before_unload_end_time.ToTimeTicks(); | 858 before_unload_end_time = browser_before_unload_end_time.ToTimeTicks(); |
| 868 | 859 |
| 869 // Collect UMA on the inter-process skew. | 860 // Collect UMA on the inter-process skew. |
| 870 bool is_skew_additive = false; | 861 bool is_skew_additive = false; |
| 871 if (converter.IsSkewAdditiveForMetrics()) { | 862 if (converter.IsSkewAdditiveForMetrics()) { |
| 872 is_skew_additive = true; | 863 is_skew_additive = true; |
| 873 base::TimeDelta skew = converter.GetSkewForMetrics(); | 864 base::TimeDelta skew = converter.GetSkewForMetrics(); |
| 874 if (skew >= base::TimeDelta()) { | 865 if (skew >= base::TimeDelta()) { |
| 875 UMA_HISTOGRAM_TIMES( | 866 UMA_HISTOGRAM_TIMES( |
| 876 "InterProcessTimeTicks.BrowserBehind_RendererToBrowser", skew); | 867 "InterProcessTimeTicks.BrowserBehind_RendererToBrowser", skew); |
| 877 } else { | 868 } else { |
| 878 UMA_HISTOGRAM_TIMES( | 869 UMA_HISTOGRAM_TIMES( |
| 879 "InterProcessTimeTicks.BrowserAhead_RendererToBrowser", -skew); | 870 "InterProcessTimeTicks.BrowserAhead_RendererToBrowser", -skew); |
| 880 } | 871 } |
| 881 } | 872 } |
| 882 UMA_HISTOGRAM_BOOLEAN( | 873 UMA_HISTOGRAM_BOOLEAN( |
| 883 "InterProcessTimeTicks.IsSkewAdditive_RendererToBrowser", | 874 "InterProcessTimeTicks.IsSkewAdditive_RendererToBrowser", |
| 884 is_skew_additive); | 875 is_skew_additive); |
| 885 | 876 |
| 877 base::TimeDelta on_before_unload_overhead_time = | |
| 878 (receive_before_unload_ack_time - send_before_unload_start_time_) - | |
| 879 (renderer_before_unload_end_time - renderer_before_unload_start_time); | |
| 880 UMA_HISTOGRAM_TIMES("Navigation.OnBeforeUnloadOverheadTime", | |
| 881 on_before_unload_overhead_time); | |
| 882 | |
| 886 frame_tree_node_->navigator()->LogBeforeUnloadTime( | 883 frame_tree_node_->navigator()->LogBeforeUnloadTime( |
| 887 renderer_before_unload_start_time, renderer_before_unload_end_time); | 884 renderer_before_unload_start_time, renderer_before_unload_end_time); |
| 888 } | 885 } |
| 889 frame_tree_node_->render_manager()->OnBeforeUnloadACK( | 886 frame_tree_node_->render_manager()->OnBeforeUnloadACK( |
| 890 unload_ack_is_for_cross_site_transition_, proceed, | 887 unload_ack_is_for_cross_site_transition_, proceed, |
| 891 before_unload_end_time); | 888 before_unload_end_time); |
| 892 | 889 |
| 893 // If canceled, notify the delegate to cancel its pending navigation entry. | 890 // If canceled, notify the delegate to cancel its pending navigation entry. |
| 894 if (!proceed) | 891 if (!proceed) |
| 895 render_view_host_->GetDelegate()->DidCancelLoading(); | 892 render_view_host_->GetDelegate()->DidCancelLoading(); |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 | 1293 |
| 1297 void RenderFrameHostImpl::OpenURL(const FrameHostMsg_OpenURL_Params& params) { | 1294 void RenderFrameHostImpl::OpenURL(const FrameHostMsg_OpenURL_Params& params) { |
| 1298 OnOpenURL(params); | 1295 OnOpenURL(params); |
| 1299 } | 1296 } |
| 1300 | 1297 |
| 1301 void RenderFrameHostImpl::Stop() { | 1298 void RenderFrameHostImpl::Stop() { |
| 1302 Send(new FrameMsg_Stop(routing_id_)); | 1299 Send(new FrameMsg_Stop(routing_id_)); |
| 1303 } | 1300 } |
| 1304 | 1301 |
| 1305 void RenderFrameHostImpl::DispatchBeforeUnload(bool for_cross_site_transition) { | 1302 void RenderFrameHostImpl::DispatchBeforeUnload(bool for_cross_site_transition) { |
| 1303 // TODO(creis): Support beforeunload on subframes. For now just pretend that | |
| 1304 // the handler ran and allowed the navigation to proceed. | |
| 1305 if (GetParent() || !IsRenderFrameLive()) { | |
| 1306 // We don't have a live renderer, so just skip running beforeunload. | |
| 1307 frame_tree_node_->render_manager()->OnBeforeUnloadACK( | |
| 1308 for_cross_site_transition, true, base::TimeTicks::Now()); | |
| 1309 return; | |
| 1310 } | |
| 1306 TRACE_EVENT_ASYNC_BEGIN0( | 1311 TRACE_EVENT_ASYNC_BEGIN0( |
| 1307 "navigation", "RenderFrameHostImpl::BeforeUnload", this); | 1312 "navigation", "RenderFrameHostImpl::BeforeUnload", this); |
|
carlosk
2014/10/15 12:29:04
I moved this trace start down for it doesn't seem
| |
| 1308 // TODO(creis): Support subframes. | |
| 1309 if (GetParent() || !IsRenderFrameLive()) { | |
| 1310 // We don't have a live renderer, so just skip running beforeunload. | |
| 1311 is_waiting_for_beforeunload_ack_ = true; | |
| 1312 unload_ack_is_for_cross_site_transition_ = for_cross_site_transition; | |
| 1313 base::TimeTicks now = base::TimeTicks::Now(); | |
| 1314 OnBeforeUnloadACK(true, now, now); | |
| 1315 return; | |
| 1316 } | |
| 1317 | 1313 |
| 1318 // This may be called more than once (if the user clicks the tab close button | 1314 // This may be called more than once (if the user clicks the tab close button |
| 1319 // several times, or if she clicks the tab close button then the browser close | 1315 // several times, or if she clicks the tab close button then the browser close |
| 1320 // button), and we only send the message once. | 1316 // button), and we only send the message once. |
| 1321 if (is_waiting_for_beforeunload_ack_) { | 1317 if (is_waiting_for_beforeunload_ack_) { |
| 1322 // Some of our close messages could be for the tab, others for cross-site | 1318 // Some of our close messages could be for the tab, others for cross-site |
| 1323 // transitions. We always want to think it's for closing the tab if any | 1319 // transitions. We always want to think it's for closing the tab if any |
| 1324 // of the messages were, since otherwise it might be impossible to close | 1320 // of the messages were, since otherwise it might be impossible to close |
| 1325 // (if there was a cross-site "close" request pending when the user clicked | 1321 // (if there was a cross-site "close" request pending when the user clicked |
| 1326 // the close button). We want to keep the "for cross site" flag only if | 1322 // the close button). We want to keep the "for cross site" flag only if |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1557 // Clear any state if a pending navigation is canceled or preempted. | 1553 // Clear any state if a pending navigation is canceled or preempted. |
| 1558 if (suspended_nav_params_) | 1554 if (suspended_nav_params_) |
| 1559 suspended_nav_params_.reset(); | 1555 suspended_nav_params_.reset(); |
| 1560 | 1556 |
| 1561 TRACE_EVENT_ASYNC_END0("navigation", | 1557 TRACE_EVENT_ASYNC_END0("navigation", |
| 1562 "RenderFrameHostImpl navigation suspended", this); | 1558 "RenderFrameHostImpl navigation suspended", this); |
| 1563 navigations_suspended_ = false; | 1559 navigations_suspended_ = false; |
| 1564 } | 1560 } |
| 1565 | 1561 |
| 1566 } // namespace content | 1562 } // namespace content |
| OLD | NEW |