1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_widget_host_observer.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/base/models/table_model.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/table/table_view.h"
#include "ui/views/window/dialog_delegate.h"
namespace content {
class WebContents;
}
namespace views {
class Label;
}
// Provides functionality to display information about a hung renderer.
class HungPagesTableModel : public ui::TableModel,
public content::RenderProcessHostObserver,
public content::RenderWidgetHostObserver {
public:
class Delegate {
public:
// Notification when the model is updated (eg. new location) yet
// still hung.
virtual void TabUpdated() = 0;
// Notification when the model is destroyed.
virtual void TabDestroyed() = 0;
protected:
virtual ~Delegate() {}
};
explicit HungPagesTableModel(Delegate* delegate);
~HungPagesTableModel() override;
void InitForWebContents(content::WebContents* hung_contents,
content::RenderWidgetHost* render_widget_host,
base::RepeatingClosure hang_monitor_restarter);
// Resets the model to the uninitialized state (e.g. unregisters observers
// added by InitForWebContents and disassociates this model from any
// particular WebContents and/or RenderWidgetHost).
void Reset();
void RestartHangMonitorTimeout();
// Returns the hung RenderWidgetHost, or null if there aren't any WebContents.
content::RenderWidgetHost* GetRenderWidgetHost();
// Overridden from ui::TableModel:
int RowCount() override;
base::string16 GetText(int row, int column_id) override;
gfx::ImageSkia GetIcon(int row) override;
void SetObserver(ui::TableModelObserver* observer) override;
// Overridden from RenderProcessHostObserver:
void RenderProcessExited(
content::RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) override;
// Overridden from RenderWidgetHostObserver:
void RenderWidgetHostDestroyed(
content::RenderWidgetHost* widget_host) override;
private:
friend class HungRendererDialogViewBrowserTest;
// Used to track a single WebContents. If the WebContents is destroyed
// TabDestroyed() is invoked on the model.
class WebContentsObserverImpl : public content::WebContentsObserver {
public:
WebContentsObserverImpl(HungPagesTableModel* model,
content::WebContents* tab);
favicon::FaviconDriver* favicon_driver() {
return favicon::ContentFaviconDriver::FromWebContents(web_contents());
}
// WebContentsObserver overrides:
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
void WebContentsDestroyed() override;
private:
HungPagesTableModel* model_;
DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl);
};
// Invoked when a WebContents is destroyed. Cleans up |tab_observers_| and
// notifies the observer and delegate.
void TabDestroyed(WebContentsObserverImpl* tab);
// Invoked when a WebContents have been updated. The title or location of
// the WebContents may have changed.
void TabUpdated(WebContentsObserverImpl* tab);
std::vector<std::unique_ptr<WebContentsObserverImpl>> tab_observers_;
ui::TableModelObserver* observer_ = nullptr;
Delegate* delegate_ = nullptr;
content::RenderWidgetHost* render_widget_host_ = nullptr;
// Callback that restarts the hang timeout (e.g. if the user wants to wait
// some more until the renderer process responds).
base::RepeatingClosure hang_monitor_restarter_;
ScopedObserver<content::RenderProcessHost, content::RenderProcessHostObserver>
process_observer_;
ScopedObserver<content::RenderWidgetHost, content::RenderWidgetHostObserver>
widget_observer_;
DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel);
};
// This class displays a dialog which contains information about a hung
// renderer process.
class HungRendererDialogView : public views::DialogDelegateView,
public HungPagesTableModel::Delegate {
public:
// Factory function for creating an instance of the HungRendererDialogView
// class. At any given point only one instance can be active.
static HungRendererDialogView* Create(gfx::NativeWindow context);
// Returns a pointer to the singleton instance if any.
static HungRendererDialogView* GetInstance();
// Shows or hides the hung renderer dialog for the given WebContents.
static void Show(content::WebContents* contents,
content::RenderWidgetHost* render_widget_host,
base::RepeatingClosure hang_monitor_restarter);
static void Hide(content::WebContents* contents,
content::RenderWidgetHost* render_widget_host);
// Returns true if the frame is in the foreground.
static bool IsFrameActive(content::WebContents* contents);
virtual void ShowForWebContents(
content::WebContents* contents,
content::RenderWidgetHost* render_widget_host,
base::RepeatingClosure hang_monitor_restarter);
virtual void EndForWebContents(content::WebContents* contents,
content::RenderWidgetHost* render_widget_host);
// views::DialogDelegateView overrides:
base::string16 GetWindowTitle() const override;
bool ShouldShowCloseButton() const override;
void WindowClosing() override;
int GetDialogButtons() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
bool Cancel() override;
bool Accept() override;
bool Close() override;
bool ShouldUseCustomFrame() const override;
// HungPagesTableModel::Delegate overrides:
void TabUpdated() override;
void TabDestroyed() override;
protected:
HungRendererDialogView();
~HungRendererDialogView() override;
// views::View overrides:
void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) override;
static HungRendererDialogView* g_instance_;
private:
friend class HungRendererDialogViewBrowserTest;
// Initialize the controls in this dialog.
void Init();
// Restart the hang timer, giving the page more time.
void RestartHangTimer();
void UpdateLabels();
void CloseDialogWithNoAction();
// The label describing the list.
views::Label* info_label_;
// Controls within the dialog box.
views::TableView* hung_pages_table_;
// The model that provides the contents of the table that shows a list of
// pages affected by the hang.
std::unique_ptr<HungPagesTableModel> hung_pages_table_model_;
// Whether or not we've created controls for ourself.
bool initialized_;
DISALLOW_COPY_AND_ASSIGN(HungRendererDialogView);
};
#endif // CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
|