Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: content/browser/frame_host/render_frame_host_impl.cc

Issue 2740493004: Revert of Move beforeunload hang timer duties to its own timer. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 enabled_bindings_ = parent_->GetEnabledBindings(); 362 enabled_bindings_ = parent_->GetEnabledBindings();
363 363
364 // New child frames should inherit the nav_entry_id of their parent. 364 // New child frames should inherit the nav_entry_id of their parent.
365 set_nav_entry_id( 365 set_nav_entry_id(
366 frame_tree_node_->parent()->current_frame_host()->nav_entry_id()); 366 frame_tree_node_->parent()->current_frame_host()->nav_entry_id());
367 } 367 }
368 368
369 SetUpMojoIfNeeded(); 369 SetUpMojoIfNeeded();
370 swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind( 370 swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
371 &RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr()))); 371 &RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr())));
372 beforeunload_timeout_.reset(
373 new TimeoutMonitor(base::Bind(&RenderFrameHostImpl::BeforeUnloadTimeout,
374 weak_ptr_factory_.GetWeakPtr())));
375 372
376 if (widget_routing_id != MSG_ROUTING_NONE) { 373 if (widget_routing_id != MSG_ROUTING_NONE) {
377 // TODO(avi): Once RenderViewHostImpl has-a RenderWidgetHostImpl, the main 374 // TODO(avi): Once RenderViewHostImpl has-a RenderWidgetHostImpl, the main
378 // render frame should probably start owning the RenderWidgetHostImpl, 375 // render frame should probably start owning the RenderWidgetHostImpl,
379 // so this logic checking for an already existing RWHI should be removed. 376 // so this logic checking for an already existing RWHI should be removed.
380 // https://crbug.com/545684 377 // https://crbug.com/545684
381 render_widget_host_ = 378 render_widget_host_ =
382 RenderWidgetHostImpl::FromID(GetProcess()->GetID(), widget_routing_id); 379 RenderWidgetHostImpl::FromID(GetProcess()->GetID(), widget_routing_id);
383 if (!render_widget_host_) { 380 if (!render_widget_host_) {
384 DCHECK(frame_tree_node->parent()); 381 DCHECK(frame_tree_node->parent());
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 (receive_before_unload_ack_time - send_before_unload_start_time_) - 1462 (receive_before_unload_ack_time - send_before_unload_start_time_) -
1466 (renderer_before_unload_end_time - renderer_before_unload_start_time); 1463 (renderer_before_unload_end_time - renderer_before_unload_start_time);
1467 UMA_HISTOGRAM_TIMES("Navigation.OnBeforeUnloadOverheadTime", 1464 UMA_HISTOGRAM_TIMES("Navigation.OnBeforeUnloadOverheadTime",
1468 on_before_unload_overhead_time); 1465 on_before_unload_overhead_time);
1469 1466
1470 frame_tree_node_->navigator()->LogBeforeUnloadTime( 1467 frame_tree_node_->navigator()->LogBeforeUnloadTime(
1471 renderer_before_unload_start_time, renderer_before_unload_end_time); 1468 renderer_before_unload_start_time, renderer_before_unload_end_time);
1472 } 1469 }
1473 // Resets beforeunload waiting state. 1470 // Resets beforeunload waiting state.
1474 is_waiting_for_beforeunload_ack_ = false; 1471 is_waiting_for_beforeunload_ack_ = false;
1475 beforeunload_timeout_->Stop(); 1472 render_view_host_->GetWidget()->decrement_in_flight_event_count();
1473 render_view_host_->GetWidget()->StopHangMonitorTimeout();
1476 send_before_unload_start_time_ = base::TimeTicks(); 1474 send_before_unload_start_time_ = base::TimeTicks();
1477 1475
1478 // PlzNavigate: if the ACK is for a navigation, send it to the Navigator to 1476 // PlzNavigate: if the ACK is for a navigation, send it to the Navigator to
1479 // have the current navigation stop/proceed. Otherwise, send it to the 1477 // have the current navigation stop/proceed. Otherwise, send it to the
1480 // RenderFrameHostManager which handles closing. 1478 // RenderFrameHostManager which handles closing.
1481 if (IsBrowserSideNavigationEnabled() && unload_ack_is_for_navigation_) { 1479 if (IsBrowserSideNavigationEnabled() && unload_ack_is_for_navigation_) {
1482 // TODO(clamy): see if before_unload_end_time should be transmitted to the 1480 // TODO(clamy): see if before_unload_end_time should be transmitted to the
1483 // Navigator. 1481 // Navigator.
1484 frame_tree_node_->navigator()->OnBeforeUnloadACK( 1482 frame_tree_node_->navigator()->OnBeforeUnloadACK(
1485 frame_tree_node_, proceed); 1483 frame_tree_node_, proceed);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 } 1685 }
1688 1686
1689 void RenderFrameHostImpl::OnRunBeforeUnloadConfirm( 1687 void RenderFrameHostImpl::OnRunBeforeUnloadConfirm(
1690 const GURL& frame_url, 1688 const GURL& frame_url,
1691 bool is_reload, 1689 bool is_reload,
1692 IPC::Message* reply_msg) { 1690 IPC::Message* reply_msg) {
1693 // While a JS beforeunload dialog is showing, tabs in the same process 1691 // While a JS beforeunload dialog is showing, tabs in the same process
1694 // shouldn't process input events. 1692 // shouldn't process input events.
1695 GetProcess()->SetIgnoreInputEvents(true); 1693 GetProcess()->SetIgnoreInputEvents(true);
1696 render_view_host_->GetWidget()->StopHangMonitorTimeout(); 1694 render_view_host_->GetWidget()->StopHangMonitorTimeout();
1697 beforeunload_timeout_->Stop();
1698 delegate_->RunBeforeUnloadConfirm(this, is_reload, reply_msg); 1695 delegate_->RunBeforeUnloadConfirm(this, is_reload, reply_msg);
1699 } 1696 }
1700 1697
1701 void RenderFrameHostImpl::OnRunFileChooser(const FileChooserParams& params) { 1698 void RenderFrameHostImpl::OnRunFileChooser(const FileChooserParams& params) {
1702 // Do not allow messages with absolute paths in them as this can permit a 1699 // Do not allow messages with absolute paths in them as this can permit a
1703 // renderer to coerce the browser to perform I/O on a renderer controlled 1700 // renderer to coerce the browser to perform I/O on a renderer controlled
1704 // path. 1701 // path.
1705 if (params.default_file_name != params.default_file_name.BaseName()) { 1702 if (params.default_file_name != params.default_file_name.BaseName()) {
1706 bad_message::ReceivedBadMessage(GetProcess(), 1703 bad_message::ReceivedBadMessage(GetProcess(),
1707 bad_message::RFH_FILE_CHOOSER_PATH); 1704 bad_message::RFH_FILE_CHOOSER_PATH);
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 } 2385 }
2389 2386
2390 void RenderFrameHostImpl::ResetWaitingState() { 2387 void RenderFrameHostImpl::ResetWaitingState() {
2391 DCHECK(is_active()); 2388 DCHECK(is_active());
2392 2389
2393 // Whenever we reset the RFH state, we should not be waiting for beforeunload 2390 // Whenever we reset the RFH state, we should not be waiting for beforeunload
2394 // or close acks. We clear them here to be safe, since they can cause 2391 // or close acks. We clear them here to be safe, since they can cause
2395 // navigations to be ignored in OnDidCommitProvisionalLoad. 2392 // navigations to be ignored in OnDidCommitProvisionalLoad.
2396 if (is_waiting_for_beforeunload_ack_) { 2393 if (is_waiting_for_beforeunload_ack_) {
2397 is_waiting_for_beforeunload_ack_ = false; 2394 is_waiting_for_beforeunload_ack_ = false;
2398 beforeunload_timeout_->Stop(); 2395 render_view_host_->GetWidget()->decrement_in_flight_event_count();
2396 render_view_host_->GetWidget()->StopHangMonitorTimeout();
2399 } 2397 }
2400 send_before_unload_start_time_ = base::TimeTicks(); 2398 send_before_unload_start_time_ = base::TimeTicks();
2401 render_view_host_->is_waiting_for_close_ack_ = false; 2399 render_view_host_->is_waiting_for_close_ack_ = false;
2402 } 2400 }
2403 2401
2404 bool RenderFrameHostImpl::CanCommitOrigin( 2402 bool RenderFrameHostImpl::CanCommitOrigin(
2405 const url::Origin& origin, 2403 const url::Origin& origin,
2406 const GURL& url) { 2404 const GURL& url) {
2407 // If the --disable-web-security flag is specified, all bets are off and the 2405 // If the --disable-web-security flag is specified, all bets are off and the
2408 // renderer process can send any origin it wishes. 2406 // renderer process can send any origin it wishes.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 // Start the hang monitor in case the renderer hangs in the beforeunload 2531 // Start the hang monitor in case the renderer hangs in the beforeunload
2534 // handler. 2532 // handler.
2535 is_waiting_for_beforeunload_ack_ = true; 2533 is_waiting_for_beforeunload_ack_ = true;
2536 unload_ack_is_for_navigation_ = for_navigation; 2534 unload_ack_is_for_navigation_ = for_navigation;
2537 if (render_view_host_->GetDelegate()->IsJavaScriptDialogShowing()) { 2535 if (render_view_host_->GetDelegate()->IsJavaScriptDialogShowing()) {
2538 // If there is a JavaScript dialog up, don't bother sending the renderer 2536 // If there is a JavaScript dialog up, don't bother sending the renderer
2539 // the unload event because it is known unresponsive, waiting for the 2537 // the unload event because it is known unresponsive, waiting for the
2540 // reply from the dialog. 2538 // reply from the dialog.
2541 SimulateBeforeUnloadAck(); 2539 SimulateBeforeUnloadAck();
2542 } else { 2540 } else {
2543 beforeunload_timeout_type_ = 2541 // Increment the in-flight event count, to ensure that input events won't
2544 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_BEFORE_UNLOAD; 2542 // cancel the timeout timer.
2545 beforeunload_timeout_->Start( 2543 render_view_host_->GetWidget()->increment_in_flight_event_count();
2546 TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); 2544 render_view_host_->GetWidget()->StartHangMonitorTimeout(
2545 TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS),
2546 blink::WebInputEvent::Undefined,
2547 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_BEFORE_UNLOAD);
2547 send_before_unload_start_time_ = base::TimeTicks::Now(); 2548 send_before_unload_start_time_ = base::TimeTicks::Now();
2548 Send(new FrameMsg_BeforeUnload(routing_id_, is_reload)); 2549 Send(new FrameMsg_BeforeUnload(routing_id_, is_reload));
2549 } 2550 }
2550 } 2551 }
2551 } 2552 }
2552 2553
2553 void RenderFrameHostImpl::SimulateBeforeUnloadAck() { 2554 void RenderFrameHostImpl::SimulateBeforeUnloadAck() {
2554 DCHECK(is_waiting_for_beforeunload_ack_); 2555 DCHECK(is_waiting_for_beforeunload_ack_);
2555 base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_; 2556 base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
2556 OnBeforeUnloadACK(true, approx_renderer_start_time, base::TimeTicks::Now()); 2557 OnBeforeUnloadACK(true, approx_renderer_start_time, base::TimeTicks::Now());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 } 2606 }
2606 2607
2607 void RenderFrameHostImpl::JavaScriptDialogClosed( 2608 void RenderFrameHostImpl::JavaScriptDialogClosed(
2608 IPC::Message* reply_msg, 2609 IPC::Message* reply_msg,
2609 bool success, 2610 bool success,
2610 const base::string16& user_input, 2611 const base::string16& user_input,
2611 bool is_before_unload_dialog, 2612 bool is_before_unload_dialog,
2612 bool dialog_was_suppressed) { 2613 bool dialog_was_suppressed) {
2613 GetProcess()->SetIgnoreInputEvents(false); 2614 GetProcess()->SetIgnoreInputEvents(false);
2614 2615
2615 // If executing as part of beforeunload event handling, resume the timeout 2616 // If we are executing as part of beforeunload event handling, we don't
2616 // that was suspended when the dialog was shown in OnRunBeforeUnloadConfirm(). 2617 // want to use the regular hung_renderer_delay_ms_ if the user has agreed to
2618 // leave the current page. In this case, use the regular timeout value used
2619 // during the beforeunload handling.
2617 if (is_before_unload_dialog) { 2620 if (is_before_unload_dialog) {
2618 beforeunload_timeout_type_ = 2621 RendererUnresponsiveType type =
2619 success ? RendererUnresponsiveType::RENDERER_UNRESPONSIVE_BEFORE_UNLOAD 2622 success ? RendererUnresponsiveType::RENDERER_UNRESPONSIVE_BEFORE_UNLOAD
2620 : RendererUnresponsiveType::RENDERER_UNRESPONSIVE_DIALOG_CLOSED; 2623 : RendererUnresponsiveType::RENDERER_UNRESPONSIVE_DIALOG_CLOSED;
2621 beforeunload_timeout_->Start( 2624 render_view_host_->GetWidget()->StartHangMonitorTimeout(
2622 TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); 2625 success
2626 ? TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)
2627 : render_view_host_->GetWidget()->hung_renderer_delay(),
2628 blink::WebInputEvent::Undefined, type);
2623 } 2629 }
2624 2630
2625 SendJavaScriptDialogReply(reply_msg, success, user_input); 2631 SendJavaScriptDialogReply(reply_msg, success, user_input);
2626 2632
2627 // If we are waiting for a beforeunload ack and the user has suppressed 2633 // If we are waiting for a beforeunload ack and the user has suppressed
2628 // messages, kill the tab immediately. A page that's spamming is presumably 2634 // messages, kill the tab immediately; a page that's spamming alerts in
2629 // malicious, so there's no point in continuing to run its script and dragging 2635 // onbeforeunload is presumably malicious, so there's no point in continuing
2630 // out the process. This must be done after sending the reply since RenderView 2636 // to run its script and dragging out the process. This must be done after
2631 // can't close correctly while waiting for a response. 2637 // sending the reply since RenderView can't close correctly while waiting for
2638 // a response.
2632 if (is_before_unload_dialog && dialog_was_suppressed) { 2639 if (is_before_unload_dialog && dialog_was_suppressed) {
2633 UMA_HISTOGRAM_ENUMERATION( 2640 render_view_host_->GetWidget()->delegate()->RendererUnresponsive(
2634 "ChildProcess.HangRendererType", 2641 render_view_host_->GetWidget(),
2635 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_DIALOG_SUPPRESSED, 2642 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_DIALOG_SUPPRESSED);
2636 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_MAX);
2637
2638 SimulateBeforeUnloadAck();
2639 } 2643 }
2640 } 2644 }
2641 2645
2642 void RenderFrameHostImpl::SendJavaScriptDialogReply( 2646 void RenderFrameHostImpl::SendJavaScriptDialogReply(
2643 IPC::Message* reply_msg, 2647 IPC::Message* reply_msg,
2644 bool success, 2648 bool success,
2645 const base::string16& user_input) { 2649 const base::string16& user_input) {
2646 FrameHostMsg_RunJavaScriptDialog::WriteReplyParams(reply_msg, success, 2650 FrameHostMsg_RunJavaScriptDialog::WriteReplyParams(reply_msg, success,
2647 user_input); 2651 user_input);
2648 Send(reply_msg); 2652 Send(reply_msg);
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
3453 3457
3454 // There is no pending NavigationEntry in these cases, so pass 0 as the 3458 // There is no pending NavigationEntry in these cases, so pass 0 as the
3455 // pending_nav_entry_id. If the previous handle was a prematurely aborted 3459 // pending_nav_entry_id. If the previous handle was a prematurely aborted
3456 // navigation loaded via LoadDataWithBaseURL, propagate the entry id. 3460 // navigation loaded via LoadDataWithBaseURL, propagate the entry id.
3457 return NavigationHandleImpl::Create( 3461 return NavigationHandleImpl::Create(
3458 params.url, params.redirects, frame_tree_node_, is_renderer_initiated, 3462 params.url, params.redirects, frame_tree_node_, is_renderer_initiated,
3459 params.was_within_same_page, base::TimeTicks::Now(), 3463 params.was_within_same_page, base::TimeTicks::Now(),
3460 entry_id_for_data_nav, false); // started_from_context_menu 3464 entry_id_for_data_nav, false); // started_from_context_menu
3461 } 3465 }
3462 3466
3463 void RenderFrameHostImpl::BeforeUnloadTimeout() {
3464 if (render_view_host_->GetDelegate()->ShouldIgnoreUnresponsiveRenderer())
3465 return;
3466
3467 UMA_HISTOGRAM_ENUMERATION(
3468 "ChildProcess.HangRendererType", beforeunload_timeout_type_,
3469 RendererUnresponsiveType::RENDERER_UNRESPONSIVE_MAX);
3470
3471 SimulateBeforeUnloadAck();
3472 }
3473
3474 } // namespace content 3467 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_impl.h ('k') | content/browser/renderer_host/render_widget_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698