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

Side by Side Diff: chrome/browser/ui/views/hung_renderer_view.cc

Issue 10817009: Revert 147867 - Move the HungRendererDialogView and HungPagesTableModel classes into a header file … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/views/hung_renderer_view.h" 5 #include "chrome/browser/ui/browser_dialogs.h"
6 6
7 #if defined(OS_WIN) && !defined(USE_AURA) 7 #if defined(OS_WIN) && !defined(USE_AURA)
8 #include <windows.h> 8 #include <windows.h>
9 #endif 9 #endif
10 10
11 #include "base/i18n/rtl.h" 11 #include "base/i18n/rtl.h"
12 #include "base/memory/scoped_vector.h" 12 #include "base/memory/scoped_vector.h"
13 #include "base/process_util.h" 13 #include "base/process_util.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "chrome/browser/favicon/favicon_tab_helper.h" 15 #include "chrome/browser/favicon/favicon_tab_helper.h"
16 #include "chrome/browser/platform_util.h" 16 #include "chrome/browser/platform_util.h"
17 #include "chrome/browser/ui/browser_dialogs.h"
18 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 17 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
18 #include "chrome/browser/ui/tab_contents/tab_contents.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 19 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
20 #include "chrome/common/chrome_constants.h" 20 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/logging_chrome.h" 21 #include "chrome/common/logging_chrome.h"
22 #include "content/public/browser/render_process_host.h" 22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_view_host.h" 23 #include "content/public/browser/render_view_host.h"
24 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/result_codes.h" 25 #include "content/public/common/result_codes.h"
25 #include "grit/chromium_strings.h" 26 #include "grit/chromium_strings.h"
26 #include "grit/generated_resources.h" 27 #include "grit/generated_resources.h"
27 #include "grit/theme_resources.h" 28 #include "grit/theme_resources.h"
28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/resource/resource_bundle.h" 30 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/gfx/canvas.h" 31 #include "ui/gfx/canvas.h"
32 #include "ui/views/controls/button/text_button.h"
31 #include "ui/views/controls/image_view.h" 33 #include "ui/views/controls/image_view.h"
32 #include "ui/views/controls/label.h" 34 #include "ui/views/controls/label.h"
35 #include "ui/views/controls/table/group_table_model.h"
36 #include "ui/views/controls/table/group_table_view.h"
33 #include "ui/views/layout/grid_layout.h" 37 #include "ui/views/layout/grid_layout.h"
34 #include "ui/views/layout/layout_constants.h" 38 #include "ui/views/layout/layout_constants.h"
35 #include "ui/views/widget/widget.h" 39 #include "ui/views/widget/widget.h"
36 #include "ui/views/window/client_view.h" 40 #include "ui/views/window/client_view.h"
41 #include "ui/views/window/dialog_delegate.h"
37 42
38 #if defined(USE_AURA) 43 #if defined(USE_AURA)
39 #include "ui/aura/window.h" 44 #include "ui/aura/window.h"
40 #endif 45 #endif
41 46
42 #if defined(OS_WIN) 47 #if defined(OS_WIN)
43 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h" 48 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
44 #endif 49 #endif
45 50
46 HungRendererDialogView* HungRendererDialogView::g_instance_ = NULL; 51 class HungRendererDialogView;
52
53 using content::RenderViewHost;
54 using content::WebContents;
55
56 namespace {
57 // We only support showing one of these at a time per app.
58 HungRendererDialogView* g_instance = NULL;
59 }
60
61 ///////////////////////////////////////////////////////////////////////////////
62 // HungPagesTableModel
63
64 class HungPagesTableModel : public views::GroupTableModel {
65 public:
66 // The Delegate is notified any time a WebContents the model is listening to
67 // is destroyed.
68 class Delegate {
69 public:
70 virtual void TabDestroyed() = 0;
71
72 protected:
73 virtual ~Delegate() {}
74 };
75
76 explicit HungPagesTableModel(Delegate* delegate);
77 virtual ~HungPagesTableModel();
78
79 void InitForWebContents(WebContents* hung_contents);
80
81 // Returns the first RenderProcessHost, or NULL if there aren't any
82 // WebContents.
83 content::RenderProcessHost* GetRenderProcessHost();
84
85 // Returns the first RenderViewHost, or NULL if there aren't any WebContents.
86 RenderViewHost* GetRenderViewHost();
87
88 // Overridden from views::GroupTableModel:
89 virtual int RowCount();
90 virtual string16 GetText(int row, int column_id);
91 virtual gfx::ImageSkia GetIcon(int row);
92 virtual void SetObserver(ui::TableModelObserver* observer);
93 virtual void GetGroupRangeForItem(int item, views::GroupRange* range);
94
95 private:
96 // Used to track a single WebContents. If the WebContents is destroyed
97 // TabDestroyed() is invoked on the model.
98 class WebContentsObserverImpl : public content::WebContentsObserver {
99 public:
100 WebContentsObserverImpl(HungPagesTableModel* model,
101 TabContents* tab);
102
103 WebContents* web_contents() const {
104 return content::WebContentsObserver::web_contents();
105 }
106
107 FaviconTabHelper* favicon_tab_helper() {
108 return tab_->favicon_tab_helper();
109 }
110
111 // WebContentsObserver overrides:
112 virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
113 virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE;
114
115 private:
116 HungPagesTableModel* model_;
117 TabContents* tab_;
118
119 DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl);
120 };
121
122 // Invoked when a WebContents is destroyed. Cleans up |tab_observers_| and
123 // notifies the observer and delegate.
124 void TabDestroyed(WebContentsObserverImpl* tab);
125
126 typedef ScopedVector<WebContentsObserverImpl> TabObservers;
127 TabObservers tab_observers_;
128
129 ui::TableModelObserver* observer_;
130 Delegate* delegate_;
131
132 DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel);
133 };
47 134
48 /////////////////////////////////////////////////////////////////////////////// 135 ///////////////////////////////////////////////////////////////////////////////
49 // HungPagesTableModel, public: 136 // HungPagesTableModel, public:
50 137
51 HungPagesTableModel::HungPagesTableModel(Delegate* delegate) 138 HungPagesTableModel::HungPagesTableModel(Delegate* delegate)
52 : observer_(NULL), 139 : observer_(NULL),
53 delegate_(delegate) { 140 delegate_(delegate) {
54 } 141 }
55 142
56 HungPagesTableModel::~HungPagesTableModel() { 143 HungPagesTableModel::~HungPagesTableModel() {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 239 }
153 240
154 void HungPagesTableModel::WebContentsObserverImpl::WebContentsDestroyed( 241 void HungPagesTableModel::WebContentsObserverImpl::WebContentsDestroyed(
155 WebContents* tab) { 242 WebContents* tab) {
156 model_->TabDestroyed(this); 243 model_->TabDestroyed(this);
157 } 244 }
158 245
159 /////////////////////////////////////////////////////////////////////////////// 246 ///////////////////////////////////////////////////////////////////////////////
160 // HungRendererDialogView 247 // HungRendererDialogView
161 248
249 class HungRendererDialogView : public views::DialogDelegateView,
250 public views::ButtonListener,
251 public HungPagesTableModel::Delegate {
252 public:
253 HungRendererDialogView();
254 ~HungRendererDialogView();
255
256 void ShowForWebContents(WebContents* contents);
257 void EndForWebContents(WebContents* contents);
258
259 // views::DialogDelegateView overrides:
260 virtual string16 GetWindowTitle() const OVERRIDE;
261 virtual void WindowClosing() OVERRIDE;
262 virtual int GetDialogButtons() const OVERRIDE;
263 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE;
264 virtual views::View* GetExtraView() OVERRIDE;
265 virtual bool Accept(bool window_closing) OVERRIDE;
266 virtual views::View* GetContentsView() OVERRIDE;
267
268 // views::ButtonListener overrides:
269 virtual void ButtonPressed(views::Button* sender,
270 const views::Event& event) OVERRIDE;
271
272 // HungPagesTableModel::Delegate overrides:
273 virtual void TabDestroyed() OVERRIDE;
274
275 protected:
276 // views::View overrides:
277 virtual void ViewHierarchyChanged(bool is_add,
278 views::View* parent,
279 views::View* child) OVERRIDE;
280
281 private:
282 // Initialize the controls in this dialog.
283 void Init();
284 void CreateKillButtonView();
285
286 // Returns the bounds the dialog should be displayed at to be meaningfully
287 // associated with the specified WebContents.
288 gfx::Rect GetDisplayBounds(WebContents* contents);
289
290 static void InitClass();
291
292 // Controls within the dialog box.
293 views::GroupTableView* hung_pages_table_;
294
295 // The button we insert into the ClientView to kill the errant process. This
296 // is parented to a container view that uses a grid layout to align it
297 // properly.
298 views::TextButton* kill_button_;
299 views::View* kill_button_container_;
300
301 // The model that provides the contents of the table that shows a list of
302 // pages affected by the hang.
303 scoped_ptr<HungPagesTableModel> hung_pages_table_model_;
304
305 // Whether or not we've created controls for ourself.
306 bool initialized_;
307
308 // An amusing icon image.
309 static gfx::ImageSkia* frozen_icon_;
310
311 DISALLOW_COPY_AND_ASSIGN(HungRendererDialogView);
312 };
313
162 // static 314 // static
163 gfx::ImageSkia* HungRendererDialogView::frozen_icon_ = NULL; 315 gfx::ImageSkia* HungRendererDialogView::frozen_icon_ = NULL;
164 316
165 // The distance in pixels from the top of the relevant contents to place the 317 // The distance in pixels from the top of the relevant contents to place the
166 // warning window. 318 // warning window.
167 static const int kOverlayContentsOffsetY = 50; 319 static const int kOverlayContentsOffsetY = 50;
168 320
169 // The dimensions of the hung pages list table view, in pixels. 321 // The dimensions of the hung pages list table view, in pixels.
170 static const int kTableViewWidth = 300; 322 static const int kTableViewWidth = 300;
171 static const int kTableViewHeight = 100; 323 static const int kTableViewHeight = 100;
172 324
173 /////////////////////////////////////////////////////////////////////////////// 325 ///////////////////////////////////////////////////////////////////////////////
174 // HungRendererDialogView, public: 326 // HungRendererDialogView, public:
175 327
176 #if !defined(OS_WIN)
177
178 // static
179 HungRendererDialogView* HungRendererDialogView::Create() {
180 if (!g_instance_) {
181 g_instance_ = new HungRendererDialogView;
182 views::Widget::CreateWindow(g_instance_);
183 }
184 return g_instance_;
185 }
186 #endif // defined(OS_WIN)
187
188 // static
189 HungRendererDialogView* HungRendererDialogView::GetInstance() {
190 return g_instance_;
191 }
192
193 HungRendererDialogView::HungRendererDialogView() 328 HungRendererDialogView::HungRendererDialogView()
194 : hung_pages_table_(NULL), 329 : hung_pages_table_(NULL),
195 kill_button_(NULL), 330 kill_button_(NULL),
196 kill_button_container_(NULL), 331 kill_button_container_(NULL),
197 initialized_(false) { 332 initialized_(false) {
198 InitClass(); 333 InitClass();
199 } 334 }
200 335
201 HungRendererDialogView::~HungRendererDialogView() { 336 HungRendererDialogView::~HungRendererDialogView() {
202 hung_pages_table_->SetModel(NULL); 337 hung_pages_table_->SetModel(NULL);
203 } 338 }
204 339
205 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { 340 void HungRendererDialogView::ShowForWebContents(WebContents* contents) {
206 DCHECK(contents && GetWidget()); 341 DCHECK(contents && GetWidget());
207 342
208 // Don't show the warning unless the foreground window is the frame, or this 343 // Don't show the warning unless the foreground window is the frame, or this
209 // window (but still invisible). If the user has another window or 344 // window (but still invisible). If the user has another window or
210 // application selected, activating ourselves is rude. 345 // application selected, activating ourselves is rude.
211 if (!IsFrameActive(contents)) 346 gfx::NativeView frame_view =
347 platform_util::GetTopLevel(contents->GetNativeView());
348 if (!platform_util::IsWindowActive(frame_view) &&
349 !platform_util::IsWindowActive(GetWidget()->GetNativeWindow())) {
212 return; 350 return;
351 }
213 352
214 if (!GetWidget()->IsActive()) { 353 if (!GetWidget()->IsActive()) {
215 gfx::Rect bounds = GetDisplayBounds(contents); 354 gfx::Rect bounds = GetDisplayBounds(contents);
216
217 gfx::NativeView frame_view =
218 platform_util::GetTopLevel(contents->GetNativeView());
219
220 views::Widget* insert_after = 355 views::Widget* insert_after =
221 views::Widget::GetWidgetForNativeView(frame_view); 356 views::Widget::GetWidgetForNativeView(frame_view);
222 GetWidget()->SetBoundsConstrained(bounds); 357 GetWidget()->SetBoundsConstrained(bounds);
223 if (insert_after) 358 if (insert_after)
224 GetWidget()->StackAboveWidget(insert_after); 359 GetWidget()->StackAboveWidget(insert_after);
225 360
226 // We only do this if the window isn't active (i.e. hasn't been shown yet, 361 // We only do this if the window isn't active (i.e. hasn't been shown yet,
227 // or is currently shown but deactivated for another WebContents). This is 362 // or is currently shown but deactivated for another WebContents). This is
228 // because this window is a singleton, and it's possible another active 363 // because this window is a singleton, and it's possible another active
229 // renderer may hang while this one is showing, and we don't want to reset 364 // renderer may hang while this one is showing, and we don't want to reset
(...skipping 18 matching lines...) Expand all
248 383
249 /////////////////////////////////////////////////////////////////////////////// 384 ///////////////////////////////////////////////////////////////////////////////
250 // HungRendererDialogView, views::DialogDelegate implementation: 385 // HungRendererDialogView, views::DialogDelegate implementation:
251 386
252 string16 HungRendererDialogView::GetWindowTitle() const { 387 string16 HungRendererDialogView::GetWindowTitle() const {
253 return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE); 388 return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
254 } 389 }
255 390
256 void HungRendererDialogView::WindowClosing() { 391 void HungRendererDialogView::WindowClosing() {
257 // We are going to be deleted soon, so make sure our instance is destroyed. 392 // We are going to be deleted soon, so make sure our instance is destroyed.
258 g_instance_ = NULL; 393 g_instance = NULL;
259 } 394 }
260 395
261 int HungRendererDialogView::GetDialogButtons() const { 396 int HungRendererDialogView::GetDialogButtons() const {
262 // We specifically don't want a CANCEL button here because that code path is 397 // We specifically don't want a CANCEL button here because that code path is
263 // also called when the window is closed by the user clicking the X button in 398 // also called when the window is closed by the user clicking the X button in
264 // the window's titlebar, and also if we call Window::Close. Rather, we want 399 // the window's titlebar, and also if we call Window::Close. Rather, we want
265 // the OK button to wait for responsiveness (and close the dialog) and our 400 // the OK button to wait for responsiveness (and close the dialog) and our
266 // additional button (which we create) to kill the process (which will result 401 // additional button (which we create) to kill the process (which will result
267 // in the dialog being destroyed). 402 // in the dialog being destroyed).
268 return ui::DIALOG_BUTTON_OK; 403 return ui::DIALOG_BUTTON_OK;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 /////////////////////////////////////////////////////////////////////////////// 461 ///////////////////////////////////////////////////////////////////////////////
327 // HungRendererDialogView, views::View overrides: 462 // HungRendererDialogView, views::View overrides:
328 463
329 void HungRendererDialogView::ViewHierarchyChanged(bool is_add, 464 void HungRendererDialogView::ViewHierarchyChanged(bool is_add,
330 views::View* parent, 465 views::View* parent,
331 views::View* child) { 466 views::View* child) {
332 if (!initialized_ && is_add && child == this && GetWidget()) 467 if (!initialized_ && is_add && child == this && GetWidget())
333 Init(); 468 Init();
334 } 469 }
335 470
336 bool HungRendererDialogView::IsFrameActive(WebContents* contents) {
337 gfx::NativeView frame_view =
338 platform_util::GetTopLevel(contents->GetNativeView());
339 if (!platform_util::IsWindowActive(frame_view) &&
340 !platform_util::IsWindowActive(GetWidget()->GetNativeWindow())) {
341 return false;
342 }
343 return true;
344 }
345
346 /////////////////////////////////////////////////////////////////////////////// 471 ///////////////////////////////////////////////////////////////////////////////
347 // HungRendererDialogView, private: 472 // HungRendererDialogView, private:
348 473
349 void HungRendererDialogView::Init() { 474 void HungRendererDialogView::Init() {
350 views::ImageView* frozen_icon_view = new views::ImageView; 475 views::ImageView* frozen_icon_view = new views::ImageView;
351 frozen_icon_view->SetImage(frozen_icon_); 476 frozen_icon_view->SetImage(frozen_icon_);
352 477
353 views::Label* info_label = new views::Label( 478 views::Label* info_label = new views::Label(
354 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER)); 479 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER));
355 info_label->SetMultiLine(true); 480 info_label->SetMultiLine(true);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 // static 567 // static
443 void HungRendererDialogView::InitClass() { 568 void HungRendererDialogView::InitClass() {
444 static bool initialized = false; 569 static bool initialized = false;
445 if (!initialized) { 570 if (!initialized) {
446 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 571 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
447 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON); 572 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON);
448 initialized = true; 573 initialized = true;
449 } 574 }
450 } 575 }
451 576
577 static HungRendererDialogView* CreateHungRendererDialogView() {
578 HungRendererDialogView* cv = new HungRendererDialogView;
579 views::Widget::CreateWindow(cv);
580 return cv;
581 }
582
452 namespace chrome { 583 namespace chrome {
453 584
454 void ShowHungRendererDialog(WebContents* contents) { 585 void ShowHungRendererDialog(WebContents* contents) {
455 if (!logging::DialogsAreSuppressed()) { 586 if (!logging::DialogsAreSuppressed()) {
456 HungRendererDialogView* view = HungRendererDialogView::Create(); 587 if (!g_instance)
457 view->ShowForWebContents(contents); 588 g_instance = CreateHungRendererDialogView();
589 g_instance->ShowForWebContents(contents);
458 } 590 }
459 } 591 }
460 592
461 void HideHungRendererDialog(WebContents* contents) { 593 void HideHungRendererDialog(WebContents* contents) {
462 if (!logging::DialogsAreSuppressed() && 594 if (!logging::DialogsAreSuppressed() && g_instance)
463 HungRendererDialogView::GetInstance()) 595 g_instance->EndForWebContents(contents);
464 HungRendererDialogView::GetInstance()->EndForWebContents(contents);
465 } 596 }
466 597
467 } // namespace chrome 598 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/hung_renderer_view.h ('k') | chrome/browser/ui/views/hung_renderer_view_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698