| 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 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "chrome/browser/platform_util.h" | 10 #include "chrome/browser/platform_util.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 HungRendererDialogView::GetInstance()->EndForWebContents(contents); | 216 HungRendererDialogView::GetInstance()->EndForWebContents(contents); |
| 217 } | 217 } |
| 218 | 218 |
| 219 // static | 219 // static |
| 220 bool HungRendererDialogView::IsFrameActive(WebContents* contents) { | 220 bool HungRendererDialogView::IsFrameActive(WebContents* contents) { |
| 221 gfx::NativeWindow window = | 221 gfx::NativeWindow window = |
| 222 platform_util::GetTopLevel(contents->GetNativeView()); | 222 platform_util::GetTopLevel(contents->GetNativeView()); |
| 223 return platform_util::IsWindowActive(window); | 223 return platform_util::IsWindowActive(window); |
| 224 } | 224 } |
| 225 | 225 |
| 226 // static | |
| 227 void HungRendererDialogView::KillRendererProcess( | |
| 228 content::RenderProcessHost* rph) { | |
| 229 #if defined(OS_WIN) | |
| 230 // Try to generate a crash report for the hung process. | |
| 231 CrashDumpAndTerminateHungChildProcess(rph->GetHandle()); | |
| 232 #else | |
| 233 rph->Shutdown(content::RESULT_CODE_HUNG, false); | |
| 234 #endif | |
| 235 } | |
| 236 | |
| 237 | |
| 238 HungRendererDialogView::HungRendererDialogView() | 226 HungRendererDialogView::HungRendererDialogView() |
| 239 : info_label_(nullptr), | 227 : info_label_(nullptr), |
| 240 hung_pages_table_(nullptr), | 228 hung_pages_table_(nullptr), |
| 241 kill_button_(nullptr), | 229 kill_button_(nullptr), |
| 242 initialized_(false) { | 230 initialized_(false), |
| 231 kill_button_clicked_(false) { |
| 243 InitClass(); | 232 InitClass(); |
| 244 } | 233 } |
| 245 | 234 |
| 246 HungRendererDialogView::~HungRendererDialogView() { | 235 HungRendererDialogView::~HungRendererDialogView() { |
| 247 hung_pages_table_->SetModel(NULL); | 236 hung_pages_table_->SetModel(NULL); |
| 248 } | 237 } |
| 249 | 238 |
| 250 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { | 239 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { |
| 251 DCHECK(contents && GetWidget()); | 240 DCHECK(contents && GetWidget()); |
| 252 | 241 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 IDS_BROWSER_HANGMONITOR_RENDERER_TITLE, | 314 IDS_BROWSER_HANGMONITOR_RENDERER_TITLE, |
| 326 hung_pages_table_model_->RowCount()); | 315 hung_pages_table_model_->RowCount()); |
| 327 } | 316 } |
| 328 | 317 |
| 329 void HungRendererDialogView::WindowClosing() { | 318 void HungRendererDialogView::WindowClosing() { |
| 330 // We are going to be deleted soon, so make sure our instance is destroyed. | 319 // We are going to be deleted soon, so make sure our instance is destroyed. |
| 331 g_instance_ = NULL; | 320 g_instance_ = NULL; |
| 332 } | 321 } |
| 333 | 322 |
| 334 int HungRendererDialogView::GetDialogButtons() const { | 323 int HungRendererDialogView::GetDialogButtons() const { |
| 335 // We specifically don't want a CANCEL button here because that code path is | 324 return ui::DIALOG_BUTTON_CANCEL; |
| 336 // also called when the window is closed by the user clicking the X button in | |
| 337 // the window's titlebar, and also if we call Window::Close. Rather, we want | |
| 338 // the OK button to wait for responsiveness (and close the dialog) and our | |
| 339 // additional button (which we create) to kill the process (which will result | |
| 340 // in the dialog being destroyed). | |
| 341 return ui::DIALOG_BUTTON_OK; | |
| 342 } | 325 } |
| 343 | 326 |
| 344 base::string16 HungRendererDialogView::GetDialogButtonLabel( | 327 base::string16 HungRendererDialogView::GetDialogButtonLabel( |
| 345 ui::DialogButton button) const { | 328 ui::DialogButton button) const { |
| 346 if (button == ui::DIALOG_BUTTON_OK) | 329 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button); |
| 347 return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); | 330 return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); |
| 348 return views::DialogDelegateView::GetDialogButtonLabel(button); | |
| 349 } | 331 } |
| 350 | 332 |
| 351 views::View* HungRendererDialogView::CreateExtraView() { | 333 views::View* HungRendererDialogView::CreateExtraView() { |
| 352 DCHECK(!kill_button_); | 334 DCHECK(!kill_button_); |
| 353 kill_button_ = new views::LabelButton(this, | 335 kill_button_ = new views::LabelButton(this, |
| 354 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END)); | 336 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END)); |
| 355 kill_button_->SetStyle(views::Button::STYLE_BUTTON); | 337 kill_button_->SetStyle(views::Button::STYLE_BUTTON); |
| 356 return kill_button_; | 338 return kill_button_; |
| 357 } | 339 } |
| 358 | 340 |
| 359 bool HungRendererDialogView::Accept(bool window_closing) { | 341 bool HungRendererDialogView::Cancel() { |
| 360 // Don't do anything if we're being called only because the dialog is being | |
| 361 // destroyed and we don't supply a Cancel function... | |
| 362 if (window_closing) | |
| 363 return true; | |
| 364 | |
| 365 // Start waiting again for responsiveness. | 342 // Start waiting again for responsiveness. |
| 366 if (hung_pages_table_model_->GetRenderViewHost()) { | 343 if (!kill_button_clicked_ && |
| 344 hung_pages_table_model_->GetRenderViewHost()) { |
| 367 hung_pages_table_model_->GetRenderViewHost() | 345 hung_pages_table_model_->GetRenderViewHost() |
| 368 ->GetWidget() | 346 ->GetWidget() |
| 369 ->RestartHangMonitorTimeout(); | 347 ->RestartHangMonitorTimeout(); |
| 370 } | 348 } |
| 371 return true; | 349 return true; |
| 372 } | 350 } |
| 373 | 351 |
| 374 | |
| 375 bool HungRendererDialogView::UseNewStyleForThisDialog() const { | 352 bool HungRendererDialogView::UseNewStyleForThisDialog() const { |
| 376 #if defined(OS_WIN) | 353 #if defined(OS_WIN) |
| 377 // Use the old dialog style without Aero glass, otherwise the dialog will be | 354 // Use the old dialog style without Aero glass, otherwise the dialog will be |
| 378 // visually constrained to browser window bounds. See http://crbug.com/323278 | 355 // visually constrained to browser window bounds. See http://crbug.com/323278 |
| 379 return ui::win::IsAeroGlassEnabled(); | 356 return ui::win::IsAeroGlassEnabled(); |
| 380 #else | 357 #else |
| 381 return views::DialogDelegateView::UseNewStyleForThisDialog(); | 358 return views::DialogDelegateView::UseNewStyleForThisDialog(); |
| 382 #endif | 359 #endif |
| 383 } | 360 } |
| 384 | 361 |
| 385 /////////////////////////////////////////////////////////////////////////////// | 362 /////////////////////////////////////////////////////////////////////////////// |
| 386 // HungRendererDialogView, views::ButtonListener implementation: | 363 // HungRendererDialogView, views::ButtonListener implementation: |
| 387 | 364 |
| 388 void HungRendererDialogView::ButtonPressed( | 365 void HungRendererDialogView::ButtonPressed( |
| 389 views::Button* sender, const ui::Event& event) { | 366 views::Button* sender, const ui::Event& event) { |
| 390 if (sender == kill_button_ && | 367 DCHECK_EQ(kill_button_, sender); |
| 391 hung_pages_table_model_->GetRenderProcessHost()) { | 368 kill_button_clicked_ = true; |
| 392 KillRendererProcess(hung_pages_table_model_->GetRenderProcessHost()); | 369 content::RenderProcessHost* rph = |
| 393 } | 370 hung_pages_table_model_->GetRenderProcessHost(); |
| 371 if (!rph) |
| 372 return; |
| 373 #if defined(OS_WIN) |
| 374 // Try to generate a crash report for the hung process. |
| 375 CrashDumpAndTerminateHungChildProcess(rph->GetHandle()); |
| 376 #else |
| 377 rph->Shutdown(content::RESULT_CODE_HUNG, false); |
| 378 #endif |
| 394 } | 379 } |
| 395 | 380 |
| 396 /////////////////////////////////////////////////////////////////////////////// | 381 /////////////////////////////////////////////////////////////////////////////// |
| 397 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: | 382 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: |
| 398 | 383 |
| 399 void HungRendererDialogView::TabDestroyed() { | 384 void HungRendererDialogView::TabDestroyed() { |
| 400 GetWidget()->Close(); | 385 GetWidget()->Close(); |
| 401 } | 386 } |
| 402 | 387 |
| 403 /////////////////////////////////////////////////////////////////////////////// | 388 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 | 447 |
| 463 // static | 448 // static |
| 464 void HungRendererDialogView::InitClass() { | 449 void HungRendererDialogView::InitClass() { |
| 465 static bool initialized = false; | 450 static bool initialized = false; |
| 466 if (!initialized) { | 451 if (!initialized) { |
| 467 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 452 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 468 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON); | 453 frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON); |
| 469 initialized = true; | 454 initialized = true; |
| 470 } | 455 } |
| 471 } | 456 } |
| OLD | NEW |