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

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
« no previous file with comments | « chrome/browser/ui/views/hung_renderer_view_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,6 +4,29 @@
#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 "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"
+
+// Handler function type. This function is invoked when a button on the metro
+// dialog box is clicked.
+typedef void (*ButtonPressedHandler)();
+
+// 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,
+ ButtonPressedHandler button1_handler,
+ ButtonPressedHandler button2_handler);
+
+typedef void (*MetroDismissDialogBox)();
+
+using content::BrowserThread;
+
// static
HungRendererDialogView* HungRendererDialogView::Create() {
if (!g_instance_)
@@ -11,10 +34,115 @@
return g_instance_;
}
+HungRendererDialogViewWin::HungRendererDialogViewWin()
+ : contents_(NULL),
+ metro_dialog_displayed_(false) {
+}
+
+HungRendererDialogViewWin::~HungRendererDialogViewWin() {
+}
+
void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) {
- HungRendererDialogView::ShowForWebContents(contents);
+ if (!base::win::IsMetroProcess()) {
sky 2012/07/24 04:25:09 There is no reason for subclassing here. Basically
ananta 2012/07/24 18:43:48 Done. The functionality to override the default hu
+ HungRendererDialogView::ShowForWebContents(contents);
+ return;
+ }
+ if (!metro_dialog_displayed_ && 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);
+
+ 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(),
+ HungRendererDialogViewWin::OnMetroKillProcess,
+ HungRendererDialogViewWin::OnMetroWait);
+ }
+ }
+ }
}
void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) {
- HungRendererDialogView::EndForWebContents(contents);
+ if (!base::win::IsMetroProcess()) {
+ HungRendererDialogView::EndForWebContents(contents);
+ return;
+ }
+ 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 HungRendererDialogViewWin::ResetMetroState() {
+ metro_dialog_displayed_ = false;
+ contents_ = NULL;
+}
+
+// static
+void HungRendererDialogViewWin::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(HungRendererDialogViewWin::OnMetroKillProcess));
+ return;
+ }
+
+ HungRendererDialogViewWin* instance =
+ static_cast<HungRendererDialogViewWin*>(GetInstance());
+ DCHECK(instance);
+ DCHECK(instance->contents_);
+
+ KillRendererProcess(
+ instance->contents_->GetRenderProcessHost()->GetHandle());
+
+ // The metro dialog box is dismissed when the button handlers are invoked.
+ instance->ResetMetroState();
+}
+
+// static
+void HungRendererDialogViewWin::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(HungRendererDialogViewWin::OnMetroWait));
+ return;
+ }
+ HungRendererDialogViewWin* instance =
+ static_cast<HungRendererDialogViewWin*>(GetInstance());
+ DCHECK(instance);
+ instance->ResetMetroState();
+}
+
+// static
+void HungRendererDialogView::KillRendererProcess(
+ base::ProcessHandle process_handle) {
+ // Try to generate a crash report for the hung process.
+ CrashDumpAndTerminateHungChildProcess(process_handle);
+}
« no previous file with comments | « chrome/browser/ui/views/hung_renderer_view_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698