| OLD | NEW |
| 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/views/hung_renderer_view.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 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "ui/views/controls/label.h" | 32 #include "ui/views/controls/label.h" |
| 33 #include "ui/views/layout/grid_layout.h" | 33 #include "ui/views/layout/grid_layout.h" |
| 34 #include "ui/views/layout/layout_constants.h" | 34 #include "ui/views/layout/layout_constants.h" |
| 35 #include "ui/views/widget/widget.h" | 35 #include "ui/views/widget/widget.h" |
| 36 #include "ui/views/window/client_view.h" | 36 #include "ui/views/window/client_view.h" |
| 37 | 37 |
| 38 #if defined(USE_AURA) | 38 #if defined(USE_AURA) |
| 39 #include "ui/aura/window.h" | 39 #include "ui/aura/window.h" |
| 40 #endif | 40 #endif |
| 41 | 41 |
| 42 #if defined(OS_WIN) | 42 // These functions allow certain chrome platforms to override the default hung |
| 43 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h" | 43 // renderer dialog. For e.g. Chrome on Windows 8 metro |
| 44 #endif | 44 bool PlatformShowCustomHungRendererDialog(WebContents* contents); |
| 45 bool PlatformHideCustomHungRendererDialog(WebContents* contents); |
| 46 |
| 47 #if !defined(OS_WIN) |
| 48 bool PlatformShowCustomHungRendererDialog(WebContents* contents) { |
| 49 return false; |
| 50 } |
| 51 |
| 52 bool PlatformHideCustomHungRendererDialog(WebContents* contents) { |
| 53 return false; |
| 54 } |
| 55 #endif // OS_WIN |
| 45 | 56 |
| 46 HungRendererDialogView* HungRendererDialogView::g_instance_ = NULL; | 57 HungRendererDialogView* HungRendererDialogView::g_instance_ = NULL; |
| 47 | 58 |
| 48 /////////////////////////////////////////////////////////////////////////////// | 59 /////////////////////////////////////////////////////////////////////////////// |
| 49 // HungPagesTableModel, public: | 60 // HungPagesTableModel, public: |
| 50 | 61 |
| 51 HungPagesTableModel::HungPagesTableModel(Delegate* delegate) | 62 HungPagesTableModel::HungPagesTableModel(Delegate* delegate) |
| 52 : observer_(NULL), | 63 : observer_(NULL), |
| 53 delegate_(delegate) { | 64 delegate_(delegate) { |
| 54 } | 65 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 // warning window. | 177 // warning window. |
| 167 static const int kOverlayContentsOffsetY = 50; | 178 static const int kOverlayContentsOffsetY = 50; |
| 168 | 179 |
| 169 // The dimensions of the hung pages list table view, in pixels. | 180 // The dimensions of the hung pages list table view, in pixels. |
| 170 static const int kTableViewWidth = 300; | 181 static const int kTableViewWidth = 300; |
| 171 static const int kTableViewHeight = 100; | 182 static const int kTableViewHeight = 100; |
| 172 | 183 |
| 173 /////////////////////////////////////////////////////////////////////////////// | 184 /////////////////////////////////////////////////////////////////////////////// |
| 174 // HungRendererDialogView, public: | 185 // HungRendererDialogView, public: |
| 175 | 186 |
| 176 #if !defined(OS_WIN) | |
| 177 | |
| 178 // static | 187 // static |
| 179 HungRendererDialogView* HungRendererDialogView::Create() { | 188 HungRendererDialogView* HungRendererDialogView::Create() { |
| 180 if (!g_instance_) { | 189 if (!g_instance_) { |
| 181 g_instance_ = new HungRendererDialogView; | 190 g_instance_ = new HungRendererDialogView; |
| 182 views::Widget::CreateWindow(g_instance_); | 191 views::Widget::CreateWindow(g_instance_); |
| 183 } | 192 } |
| 184 return g_instance_; | 193 return g_instance_; |
| 185 } | 194 } |
| 186 #endif // defined(OS_WIN) | |
| 187 | 195 |
| 188 // static | 196 // static |
| 189 HungRendererDialogView* HungRendererDialogView::GetInstance() { | 197 HungRendererDialogView* HungRendererDialogView::GetInstance() { |
| 190 return g_instance_; | 198 return g_instance_; |
| 191 } | 199 } |
| 192 | 200 |
| 201 // static |
| 202 bool HungRendererDialogView::IsFrameActive(WebContents* contents) { |
| 203 gfx::NativeView frame_view = |
| 204 platform_util::GetTopLevel(contents->GetNativeView()); |
| 205 return platform_util::IsWindowActive(frame_view); |
| 206 } |
| 207 |
| 208 #if !defined(OS_WIN) |
| 209 // static |
| 210 void HungRendererDialogView::KillRendererProcess( |
| 211 base::ProcessHandle process_handle) { |
| 212 base::KillProcess(process_handle, content::RESULT_CODE_HUNG, false); |
| 213 } |
| 214 #endif // OS_WIN |
| 215 |
| 216 |
| 193 HungRendererDialogView::HungRendererDialogView() | 217 HungRendererDialogView::HungRendererDialogView() |
| 194 : hung_pages_table_(NULL), | 218 : hung_pages_table_(NULL), |
| 195 kill_button_(NULL), | 219 kill_button_(NULL), |
| 196 kill_button_container_(NULL), | 220 kill_button_container_(NULL), |
| 197 initialized_(false) { | 221 initialized_(false) { |
| 198 InitClass(); | 222 InitClass(); |
| 199 } | 223 } |
| 200 | 224 |
| 201 HungRendererDialogView::~HungRendererDialogView() { | 225 HungRendererDialogView::~HungRendererDialogView() { |
| 202 hung_pages_table_->SetModel(NULL); | 226 hung_pages_table_->SetModel(NULL); |
| 203 } | 227 } |
| 204 | 228 |
| 205 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { | 229 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { |
| 206 DCHECK(contents && GetWidget()); | 230 DCHECK(contents && GetWidget()); |
| 207 | 231 |
| 208 // Don't show the warning unless the foreground window is the frame, or this | 232 // 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 | 233 // window (but still invisible). If the user has another window or |
| 210 // application selected, activating ourselves is rude. | 234 // application selected, activating ourselves is rude. |
| 211 if (!IsFrameActive(contents)) | 235 if (!IsFrameActive(contents) && |
| 236 !platform_util::IsWindowActive(GetWidget()->GetNativeWindow())) |
| 212 return; | 237 return; |
| 213 | 238 |
| 214 if (!GetWidget()->IsActive()) { | 239 if (!GetWidget()->IsActive()) { |
| 215 gfx::Rect bounds = GetDisplayBounds(contents); | 240 gfx::Rect bounds = GetDisplayBounds(contents); |
| 216 | 241 |
| 217 gfx::NativeView frame_view = | 242 gfx::NativeView frame_view = |
| 218 platform_util::GetTopLevel(contents->GetNativeView()); | 243 platform_util::GetTopLevel(contents->GetNativeView()); |
| 219 | 244 |
| 220 views::Widget* insert_after = | 245 views::Widget* insert_after = |
| 221 views::Widget::GetWidgetForNativeView(frame_view); | 246 views::Widget::GetWidgetForNativeView(frame_view); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 // HungRendererDialogView, views::ButtonListener implementation: | 324 // HungRendererDialogView, views::ButtonListener implementation: |
| 300 | 325 |
| 301 void HungRendererDialogView::ButtonPressed( | 326 void HungRendererDialogView::ButtonPressed( |
| 302 views::Button* sender, const views::Event& event) { | 327 views::Button* sender, const views::Event& event) { |
| 303 if (sender == kill_button_ && | 328 if (sender == kill_button_ && |
| 304 hung_pages_table_model_->GetRenderProcessHost()) { | 329 hung_pages_table_model_->GetRenderProcessHost()) { |
| 305 | 330 |
| 306 base::ProcessHandle process_handle = | 331 base::ProcessHandle process_handle = |
| 307 hung_pages_table_model_->GetRenderProcessHost()->GetHandle(); | 332 hung_pages_table_model_->GetRenderProcessHost()->GetHandle(); |
| 308 | 333 |
| 309 #if defined(OS_WIN) | 334 KillRendererProcess(process_handle); |
| 310 // Try to generate a crash report for the hung process. | |
| 311 CrashDumpAndTerminateHungChildProcess(process_handle); | |
| 312 #else | |
| 313 // Kill the process. | |
| 314 base::KillProcess(process_handle, content::RESULT_CODE_HUNG, false); | |
| 315 #endif | |
| 316 } | 335 } |
| 317 } | 336 } |
| 318 | 337 |
| 319 /////////////////////////////////////////////////////////////////////////////// | 338 /////////////////////////////////////////////////////////////////////////////// |
| 320 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: | 339 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: |
| 321 | 340 |
| 322 void HungRendererDialogView::TabDestroyed() { | 341 void HungRendererDialogView::TabDestroyed() { |
| 323 GetWidget()->Close(); | 342 GetWidget()->Close(); |
| 324 } | 343 } |
| 325 | 344 |
| 326 /////////////////////////////////////////////////////////////////////////////// | 345 /////////////////////////////////////////////////////////////////////////////// |
| 327 // HungRendererDialogView, views::View overrides: | 346 // HungRendererDialogView, views::View overrides: |
| 328 | 347 |
| 329 void HungRendererDialogView::ViewHierarchyChanged(bool is_add, | 348 void HungRendererDialogView::ViewHierarchyChanged(bool is_add, |
| 330 views::View* parent, | 349 views::View* parent, |
| 331 views::View* child) { | 350 views::View* child) { |
| 332 if (!initialized_ && is_add && child == this && GetWidget()) | 351 if (!initialized_ && is_add && child == this && GetWidget()) |
| 333 Init(); | 352 Init(); |
| 334 } | 353 } |
| 335 | 354 |
| 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 /////////////////////////////////////////////////////////////////////////////// | 355 /////////////////////////////////////////////////////////////////////////////// |
| 347 // HungRendererDialogView, private: | 356 // HungRendererDialogView, private: |
| 348 | 357 |
| 349 void HungRendererDialogView::Init() { | 358 void HungRendererDialogView::Init() { |
| 350 views::ImageView* frozen_icon_view = new views::ImageView; | 359 views::ImageView* frozen_icon_view = new views::ImageView; |
| 351 frozen_icon_view->SetImage(frozen_icon_); | 360 frozen_icon_view->SetImage(frozen_icon_); |
| 352 | 361 |
| 353 views::Label* info_label = new views::Label( | 362 views::Label* info_label = new views::Label( |
| 354 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER)); | 363 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER)); |
| 355 info_label->SetMultiLine(true); | 364 info_label->SetMultiLine(true); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 if (!initialized) { | 454 if (!initialized) { |
| 446 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 455 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 447 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON); | 456 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON); |
| 448 initialized = true; | 457 initialized = true; |
| 449 } | 458 } |
| 450 } | 459 } |
| 451 | 460 |
| 452 namespace chrome { | 461 namespace chrome { |
| 453 | 462 |
| 454 void ShowHungRendererDialog(WebContents* contents) { | 463 void ShowHungRendererDialog(WebContents* contents) { |
| 455 if (!logging::DialogsAreSuppressed()) { | 464 if (!logging::DialogsAreSuppressed() && |
| 465 !PlatformShowCustomHungRendererDialog(contents)) { |
| 456 HungRendererDialogView* view = HungRendererDialogView::Create(); | 466 HungRendererDialogView* view = HungRendererDialogView::Create(); |
| 457 view->ShowForWebContents(contents); | 467 view->ShowForWebContents(contents); |
| 458 } | 468 } |
| 459 } | 469 } |
| 460 | 470 |
| 461 void HideHungRendererDialog(WebContents* contents) { | 471 void HideHungRendererDialog(WebContents* contents) { |
| 462 if (!logging::DialogsAreSuppressed() && | 472 if (!logging::DialogsAreSuppressed() && |
| 473 !PlatformHideCustomHungRendererDialog(contents) && |
| 463 HungRendererDialogView::GetInstance()) | 474 HungRendererDialogView::GetInstance()) |
| 464 HungRendererDialogView::GetInstance()->EndForWebContents(contents); | 475 HungRendererDialogView::GetInstance()->EndForWebContents(contents); |
| 465 } | 476 } |
| 466 | 477 |
| 467 } // namespace chrome | 478 } // namespace chrome |
| OLD | NEW |