Index: chrome/browser/ui/views/hung_renderer_view_win.cc |
=================================================================== |
--- chrome/browser/ui/views/hung_renderer_view_win.cc (revision 147919) |
+++ chrome/browser/ui/views/hung_renderer_view_win.cc (working copy) |
@@ -4,17 +4,142 @@ |
#include "chrome/browser/ui/views/hung_renderer_view_win.h" |
+#include "base/win/metro.h" |
+#include "chrome/browser/hang_monitor/hang_crash_dump_win.h" |
+#include "chrome/browser/ui/views/hung_renderer_view.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "grit/generated_resources.h" |
+#include "ui/base/l10n/l10n_util.h" |
+ |
+// Metro functions for displaying and dismissing a dialog box. |
+typedef void (*MetroShowDialogBox)( |
+ const wchar_t* title, |
+ const wchar_t* content, |
+ const wchar_t* button1_label, |
+ const wchar_t* button2_label, |
+ base::win::MetroDialogButtonPressedHandler button1_handler, |
+ base::win::MetroDialogButtonPressedHandler button2_handler); |
+ |
+typedef void (*MetroDismissDialogBox)(); |
+ |
+using content::BrowserThread; |
+using content::WebContents; |
+ |
+HungRendererDialogMetro g_instance; |
sky
2012/07/24 22:57:03
You need to make this a pointer.
ananta
2012/07/24 23:16:37
Done. This is now accessed via the statc Create an
|
+ |
+bool PlatformShowCustomHungRendererDialog(WebContents* contents) { |
+ if (!base::win::IsMetroProcess()) |
+ return false; |
+ g_instance.Show(contents); |
+ return true; |
+} |
+ |
+bool PlatformHideCustomHungRendererDialog(WebContents* contents) { |
+ if (!base::win::IsMetroProcess()) |
+ return false; |
+ g_instance.Hide(contents); |
+ return true; |
+} |
+ |
// static |
-HungRendererDialogView* HungRendererDialogView::Create() { |
- if (!g_instance_) |
- g_instance_ = new HungRendererDialogViewWin(); |
- return g_instance_; |
+void HungRendererDialogView::KillRendererProcess( |
+ base::ProcessHandle process_handle) { |
+ // Try to generate a crash report for the hung process. |
+ CrashDumpAndTerminateHungChildProcess(process_handle); |
} |
-void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) { |
- HungRendererDialogView::ShowForWebContents(contents); |
+HungRendererDialogMetro::HungRendererDialogMetro() |
+ : contents_(NULL), |
+ metro_dialog_displayed_(false) { |
} |
-void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) { |
- HungRendererDialogView::EndForWebContents(contents); |
+HungRendererDialogMetro::~HungRendererDialogMetro() { |
} |
+ |
+void HungRendererDialogMetro::Show(WebContents* contents) { |
+ if (!metro_dialog_displayed_ && |
+ HungRendererDialogView::IsFrameActive(contents)) { |
+ HMODULE metro_dll = base::win::GetMetroModule(); |
+ DCHECK(metro_dll); |
+ if (metro_dll) { |
+ MetroShowDialogBox show_dialog_box = reinterpret_cast<MetroShowDialogBox> |
+ (::GetProcAddress(metro_dll, "ShowDialogBox")); |
+ DCHECK(show_dialog_box); |
+ if (show_dialog_box) { |
+ string16 dialog_box_title = |
+ l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE); |
+ |
+ string16 kill_button_label = |
+ l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END); |
+ |
+ string16 wait_button_label = |
+ l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); |
+ |
+ g_instance.contents_ = contents; |
+ metro_dialog_displayed_ = true; |
+ |
+ (*show_dialog_box)(dialog_box_title.c_str(), |
+ contents->GetTitle().c_str(), |
+ kill_button_label.c_str(), |
+ wait_button_label.c_str(), |
+ HungRendererDialogMetro::OnMetroKillProcess, |
+ HungRendererDialogMetro::OnMetroWait); |
+ } |
+ } |
+ } |
+} |
+ |
+void HungRendererDialogMetro::Hide(WebContents* contents) { |
+ HMODULE metro_dll = base::win::GetMetroModule(); |
+ DCHECK(metro_dll); |
+ if (metro_dll) { |
+ MetroDismissDialogBox dismiss_dialog_box = |
+ reinterpret_cast<MetroDismissDialogBox> |
+ (::GetProcAddress(metro_dll, "DismissDialogBox")); |
+ DCHECK(dismiss_dialog_box); |
+ if (dismiss_dialog_box) { |
+ (*dismiss_dialog_box)(); |
+ ResetMetroState(); |
+ } |
+ } |
+} |
+ |
+void HungRendererDialogMetro::ResetMetroState() { |
+ metro_dialog_displayed_ = false; |
+ contents_ = NULL; |
+} |
+ |
+// static |
+void HungRendererDialogMetro::OnMetroKillProcess() { |
+ // Metro chrome will invoke these handlers on the metro thread. Ensure that |
+ // we switch to the UI thread. |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(HungRendererDialogMetro::OnMetroKillProcess)); |
+ return; |
+ } |
+ |
+ DCHECK(g_instance.contents_); |
+ |
+ HungRendererDialogView::KillRendererProcess( |
+ g_instance.contents_->GetRenderProcessHost()->GetHandle()); |
+ |
+ // The metro dialog box is dismissed when the button handlers are invoked. |
+ g_instance.ResetMetroState(); |
+} |
+ |
+// static |
+void HungRendererDialogMetro::OnMetroWait() { |
+ // Metro chrome will invoke these handlers on the metro thread. Ensure that |
+ // we switch to the UI thread. |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(HungRendererDialogMetro::OnMetroWait)); |
+ return; |
+ } |
+ |
+ g_instance.ResetMetroState(); |
+} |