hung_renderer_view.h revision 010d83a9304c5a91596085d917d248abff47903a
1ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// Use of this source code is governed by a BSD-style license that can be 3ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// found in the LICENSE file. 4ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 5ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#ifndef CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_ 6ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#define CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_ 7ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 8ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "base/memory/scoped_vector.h" 9ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "chrome/browser/favicon/favicon_tab_helper.h" 10ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "content/public/browser/web_contents_observer.h" 11ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "ui/base/models/table_model.h" 12ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "ui/views/controls/button/button.h" 13ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "ui/views/controls/table/table_grouper.h" 14ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "ui/views/controls/table/table_view.h" 15ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "ui/views/window/dialog_delegate.h" 16ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 17ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremeneknamespace content { 18686775deca8b8685eb90801495880e3abdd844c2Chris Lattnerclass WebContents; 19a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 20f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth 215595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenkonamespace views { 225595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenkoclass LabelButton; 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 24ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 25ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// Provides functionality to display information about a hung renderer. 26ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekclass HungPagesTableModel : public ui::TableModel, public views::TableGrouper { 279c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko public: 289c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko // The Delegate is notified any time a WebContents the model is listening to 29ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek // is destroyed. 30dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko class Delegate { 31dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko public: 32dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko virtual void TabDestroyed() = 0; 33dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko 3415a2aa0954bcf38411c14cf67c65e336022a7a1bDmitri Gribenko protected: 3515a2aa0954bcf38411c14cf67c65e336022a7a1bDmitri Gribenko virtual ~Delegate() {} 36dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko }; 37dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko 380c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko explicit HungPagesTableModel(Delegate* delegate); 390c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko virtual ~HungPagesTableModel(); 400c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko 410c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko void InitForWebContents(content::WebContents* hung_contents); 420c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko 430c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko // Returns the first RenderProcessHost, or NULL if there aren't any 440c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko // WebContents. 450c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko content::RenderProcessHost* GetRenderProcessHost(); 460c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko 470c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko // Returns the first RenderViewHost, or NULL if there aren't any WebContents. 480c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko content::RenderViewHost* GetRenderViewHost(); 49ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 505595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko // Overridden from ui::TableModel: 515595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko virtual int RowCount() OVERRIDE; 525595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko virtual base::string16 GetText(int row, int column_id) OVERRIDE; 535595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko virtual gfx::ImageSkia GetIcon(int row) OVERRIDE; 545595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko virtual void SetObserver(ui::TableModelObserver* observer) OVERRIDE; 555595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko 565595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko // Overridden from views::TableGrouper: 575595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko virtual void GetGroupRange(int model_index, 585595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko views::GroupRange* range) OVERRIDE; 595595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko 605595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko private: 615595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko // Used to track a single WebContents. If the WebContents is destroyed 625595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko // TabDestroyed() is invoked on the model. 635595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko class WebContentsObserverImpl : public content::WebContentsObserver { 645595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko public: 655595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko WebContentsObserverImpl(HungPagesTableModel* model, 665595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko content::WebContents* tab); 67a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 68a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek content::WebContents* web_contents() const { 69a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return content::WebContentsObserver::web_contents(); 70a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek } 719c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 729c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko FaviconTabHelper* favicon_tab_helper() { 739c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko return FaviconTabHelper::FromWebContents(web_contents()); 749c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko } 759c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 769c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko // WebContentsObserver overrides: 779c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; 789c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko virtual void WebContentsDestroyed() OVERRIDE; 799c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 809c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko private: 819c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko HungPagesTableModel* model_; 829c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 839c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl); 849c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko }; 859c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 869c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko // Invoked when a WebContents is destroyed. Cleans up |tab_observers_| and 879c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko // notifies the observer and delegate. 889c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko void TabDestroyed(WebContentsObserverImpl* tab); 899c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 909c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko typedef ScopedVector<WebContentsObserverImpl> TabObservers; 919c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko TabObservers tab_observers_; 929c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko 93a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ui::TableModelObserver* observer_; 94a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Delegate* delegate_; 95ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 96baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel); 97baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek}; 98baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek 99ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This class displays a dialog which contains information about a hung 100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// renderer process. 101ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass HungRendererDialogView : public views::DialogDelegateView, 102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines public views::ButtonListener, 103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines public HungPagesTableModel::Delegate { 104ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek public: 105ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek // Factory function for creating an instance of the HungRendererDialogView 106ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek // class. At any given point only one instance can be active. 107ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek static HungRendererDialogView* Create(gfx::NativeView context); 108 109 // Returns a pointer to the singleton instance if any. 110 static HungRendererDialogView* GetInstance(); 111 112 // Platform specific function to kill the renderer process identified by the 113 // handle passed in. 114 static void KillRendererProcess(base::ProcessHandle process_handle); 115 116 // Returns true if the frame is in the foreground. 117 static bool IsFrameActive(content::WebContents* contents); 118 119 virtual void ShowForWebContents(content::WebContents* contents); 120 virtual void EndForWebContents(content::WebContents* contents); 121 122 // views::DialogDelegateView overrides: 123 virtual base::string16 GetWindowTitle() const OVERRIDE; 124 virtual void WindowClosing() OVERRIDE; 125 virtual int GetDialogButtons() const OVERRIDE; 126 virtual base::string16 GetDialogButtonLabel( 127 ui::DialogButton button) const OVERRIDE; 128 virtual views::View* CreateExtraView() OVERRIDE; 129 virtual bool Accept(bool window_closing) OVERRIDE; 130 virtual bool UseNewStyleForThisDialog() const OVERRIDE; 131 132 // views::ButtonListener overrides: 133 virtual void ButtonPressed(views::Button* sender, 134 const ui::Event& event) OVERRIDE; 135 136 // HungPagesTableModel::Delegate overrides: 137 virtual void TabDestroyed() OVERRIDE; 138 139 protected: 140 HungRendererDialogView(); 141 virtual ~HungRendererDialogView(); 142 143 // views::View overrides: 144 virtual void ViewHierarchyChanged( 145 const ViewHierarchyChangedDetails& details) OVERRIDE; 146 147 static HungRendererDialogView* g_instance_; 148 149 private: 150 // Initialize the controls in this dialog. 151 void Init(); 152 153 static void InitClass(); 154 155 // Controls within the dialog box. 156 views::TableView* hung_pages_table_; 157 158 // The extra button inserted into the ClientView to kill the errant process. 159 views::LabelButton* kill_button_; 160 161 // The model that provides the contents of the table that shows a list of 162 // pages affected by the hang. 163 scoped_ptr<HungPagesTableModel> hung_pages_table_model_; 164 165 // Whether or not we've created controls for ourself. 166 bool initialized_; 167 168 // An amusing icon image. 169 static gfx::ImageSkia* frozen_icon_; 170 171 DISALLOW_COPY_AND_ASSIGN(HungRendererDialogView); 172}; 173 174#endif // CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_ 175