OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/render_widget_host.h" | 5 #include "chrome/browser/render_widget_host.h" |
6 | 6 |
7 #include "base/gfx/bitmap_header.h" | 7 #include "base/gfx/bitmap_header.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "chrome/app/chrome_dll_resource.h" | 9 #include "chrome/app/chrome_dll_resource.h" |
10 #include "chrome/browser/render_process_host.h" | 10 #include "chrome/browser/render_process_host.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, int routing_id) | 266 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, int routing_id) |
267 : process_(process), | 267 : process_(process), |
268 routing_id_(routing_id), | 268 routing_id_(routing_id), |
269 resize_ack_pending_(false), | 269 resize_ack_pending_(false), |
270 mouse_move_pending_(false), | 270 mouse_move_pending_(false), |
271 view_(NULL), | 271 view_(NULL), |
272 is_loading_(false), | 272 is_loading_(false), |
273 is_hidden_(false), | 273 is_hidden_(false), |
274 suppress_view_updating_(false), | 274 suppress_view_updating_(false), |
275 needs_repainting_on_restore_(false), | 275 needs_repainting_on_restore_(false), |
276 hung_renderer_factory_(this), | |
277 is_unresponsive_(false), | 276 is_unresponsive_(false), |
278 view_being_painted_(false), | 277 view_being_painted_(false), |
279 repaint_ack_pending_(false) { | 278 repaint_ack_pending_(false) { |
280 if (routing_id_ == MSG_ROUTING_NONE) | 279 if (routing_id_ == MSG_ROUTING_NONE) |
281 routing_id_ = process_->widget_helper()->GetNextRoutingID(); | 280 routing_id_ = process_->widget_helper()->GetNextRoutingID(); |
282 | 281 |
283 process_->Attach(this, routing_id_); | 282 process_->Attach(this, routing_id_); |
284 // Because the widget initializes as is_hidden_ == false, | 283 // Because the widget initializes as is_hidden_ == false, |
285 // tell the process host that we're alive. | 284 // tell the process host that we're alive. |
286 process_->WidgetRestored(); | 285 process_->WidgetRestored(); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
623 | 622 |
624 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); | 623 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); |
625 message->WriteData( | 624 message->WriteData( |
626 reinterpret_cast<const char*>(&input_event), event_size); | 625 reinterpret_cast<const char*>(&input_event), event_size); |
627 input_event_start_time_ = TimeTicks::Now(); | 626 input_event_start_time_ = TimeTicks::Now(); |
628 Send(message); | 627 Send(message); |
629 | 628 |
630 // any input event cancels a pending mouse move event | 629 // any input event cancels a pending mouse move event |
631 next_mouse_move_.reset(); | 630 next_mouse_move_.reset(); |
632 | 631 |
633 StartHangMonitorTimeout(kHungRendererDelayMs); | 632 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); |
634 } | 633 } |
635 | 634 |
636 void RenderWidgetHost::Shutdown() { | 635 void RenderWidgetHost::Shutdown() { |
637 if (process_->channel()) { | 636 if (process_->channel()) { |
638 // Tell the renderer object to close. | 637 // Tell the renderer object to close. |
639 process_->ReportExpectingClose(routing_id_); | 638 process_->ReportExpectingClose(routing_id_); |
640 bool rv = Send(new ViewMsg_Close(routing_id_)); | 639 bool rv = Send(new ViewMsg_Close(routing_id_)); |
641 DCHECK(rv); | 640 DCHECK(rv); |
642 } | 641 } |
643 | 642 |
(...skipping 22 matching lines...) Expand all Loading... | |
666 // Tell the view to die. | 665 // Tell the view to die. |
667 // Note that in the process of the view shutting down, it can call a ton | 666 // Note that in the process of the view shutting down, it can call a ton |
668 // of other messages on us. So if you do any other deinitialization here, | 667 // of other messages on us. So if you do any other deinitialization here, |
669 // do it after this call to view_->Destroy(). | 668 // do it after this call to view_->Destroy(). |
670 if (view_) | 669 if (view_) |
671 view_->Destroy(); | 670 view_->Destroy(); |
672 | 671 |
673 delete this; | 672 delete this; |
674 } | 673 } |
675 | 674 |
676 void RenderWidgetHost::RendererIsUnresponsive() { | 675 void RenderWidgetHost::CheckRendererIsUnresponsive() { |
676 // If we received a call to StopHangMonitorTimeout. | |
677 if (time_when_considered_hung_.is_null()) | |
678 return; | |
679 | |
680 // If we have not waited long enough, then wait some more. | |
681 Time now = Time::Now(); | |
682 if (now < time_when_considered_hung_) { | |
683 StartHangMonitorTimeout(time_when_considered_hung_ - now); | |
684 return; | |
685 } | |
686 | |
687 // OK, looks like we have a hung renderer! | |
677 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_HANG, | 688 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_HANG, |
678 Source<RenderWidgetHost>(this), | 689 Source<RenderWidgetHost>(this), |
679 NotificationService::NoDetails()); | 690 NotificationService::NoDetails()); |
680 is_unresponsive_ = true; | 691 is_unresponsive_ = true; |
681 NotifyRendererUnresponsive(); | 692 NotifyRendererUnresponsive(); |
682 } | 693 } |
683 | 694 |
684 void RenderWidgetHost::RendererIsResponsive() { | 695 void RenderWidgetHost::RendererIsResponsive() { |
685 if (is_unresponsive_) { | 696 if (is_unresponsive_) { |
686 is_unresponsive_ = false; | 697 is_unresponsive_ = false; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 // TODO(darin): this doesn't work if dx and dy are both non-zero! | 792 // TODO(darin): this doesn't work if dx and dy are both non-zero! |
782 DCHECK(dx == 0 || dy == 0); | 793 DCHECK(dx == 0 || dy == 0); |
783 | 794 |
784 // We expect that damaged_rect should equal bitmap_rect. | 795 // We expect that damaged_rect should equal bitmap_rect. |
785 DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); | 796 DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); |
786 | 797 |
787 backing_store->Refresh(process_->process(), bitmap, bitmap_rect); | 798 backing_store->Refresh(process_->process(), bitmap, bitmap_rect); |
788 } | 799 } |
789 | 800 |
790 void RenderWidgetHost::RestartHangMonitorTimeout() { | 801 void RenderWidgetHost::RestartHangMonitorTimeout() { |
791 hung_renderer_factory_.RevokeAll(); | 802 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); |
792 StartHangMonitorTimeout(kHungRendererDelayMs); | |
793 } | 803 } |
794 | 804 |
795 void RenderWidgetHost::StopHangMonitorTimeout() { | 805 void RenderWidgetHost::StopHangMonitorTimeout() { |
796 hung_renderer_factory_.RevokeAll(); | 806 time_when_considered_hung_ = Time(); |
797 RendererIsResponsive(); | 807 RendererIsResponsive(); |
808 | |
809 // We do not bother to stop the hung_renderer_timer_ here in case it will be | |
810 // started again shortly, which happens to be the common use case. | |
798 } | 811 } |
799 | 812 |
800 void RenderWidgetHost::StartHangMonitorTimeout(int delay) { | 813 void RenderWidgetHost::StartHangMonitorTimeout(TimeDelta delay) { |
801 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 814 time_when_considered_hung_ = Time::Now() + delay; |
802 hung_renderer_factory_.NewRunnableMethod( | 815 |
803 &RenderWidgetHost::RendererIsUnresponsive), delay); | 816 // If we already have a timer that will expire at or before the given delay, |
817 // then we have nothing more to do now. | |
818 if (hung_renderer_timer_.IsRunning() && | |
819 hung_renderer_timer_.GetCurrentDelay() <= delay) | |
820 return; | |
821 | |
822 // We need to adjust the timer to fire sooner. | |
Mike Belshe
2008/09/25 16:01:05
// Either the timer is not yet running, or we need
| |
823 hung_renderer_timer_.Stop(); | |
824 hung_renderer_timer_.Start(delay, this, | |
825 &RenderWidgetHost::CheckRendererIsUnresponsive); | |
804 } | 826 } |
805 | 827 |
806 void RenderWidgetHost::RendererExited() { | 828 void RenderWidgetHost::RendererExited() { |
807 BackingStoreManager::RemoveBackingStore(this); | 829 BackingStoreManager::RemoveBackingStore(this); |
808 } | 830 } |
809 | 831 |
810 void RenderWidgetHost::SystemThemeChanged() { | 832 void RenderWidgetHost::SystemThemeChanged() { |
811 Send(new ViewMsg_ThemeChanged(routing_id_)); | 833 Send(new ViewMsg_ThemeChanged(routing_id_)); |
812 } | 834 } |
813 | 835 |
814 | 836 |
OLD | NEW |