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

Unified Diff: chrome/browser/ui/views/hung_renderer_view_win.cc

Issue 10806079: Add support for invoking the Windows 8 metro style hung renderer dialog box. The dialog box (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 side-by-side diff with in-line comments
Download patch
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();
+}

Powered by Google App Engine
This is Rietveld 408576698