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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/hung_renderer_view_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_win.h" 5 #include "chrome/browser/ui/views/hung_renderer_view_win.h"
6 6
7 #include "base/win/metro.h"
8 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
9 #include "chrome/browser/ui/views/hung_renderer_view.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "grit/generated_resources.h"
13 #include "ui/base/l10n/l10n_util.h"
14
15 // Metro functions for displaying and dismissing a dialog box.
16 typedef void (*MetroShowDialogBox)(
17 const wchar_t* title,
18 const wchar_t* content,
19 const wchar_t* button1_label,
20 const wchar_t* button2_label,
21 base::win::MetroDialogButtonPressedHandler button1_handler,
22 base::win::MetroDialogButtonPressedHandler button2_handler);
23
24 typedef void (*MetroDismissDialogBox)();
25
26 using content::BrowserThread;
27 using content::WebContents;
28
29 HungRendererDialogMetro* HungRendererDialogMetro::g_instance_ = NULL;
30
31 bool PlatformShowCustomHungRendererDialog(WebContents* contents) {
32 if (!base::win::IsMetroProcess())
33 return false;
34
35 HungRendererDialogMetro::Create()->Show(contents);
36 return true;
37 }
38
39 bool PlatformHideCustomHungRendererDialog(WebContents* contents) {
40 if (!base::win::IsMetroProcess())
41 return false;
42
43 if (HungRendererDialogMetro::GetInstance())
44 HungRendererDialogMetro::GetInstance()->Hide(contents);
45 return true;
46 }
47
7 // static 48 // static
8 HungRendererDialogView* HungRendererDialogView::Create() { 49 void HungRendererDialogView::KillRendererProcess(
9 if (!g_instance_) 50 base::ProcessHandle process_handle) {
10 g_instance_ = new HungRendererDialogViewWin(); 51 // Try to generate a crash report for the hung process.
52 CrashDumpAndTerminateHungChildProcess(process_handle);
53 }
54
55 // static
56 HungRendererDialogMetro* HungRendererDialogMetro::Create() {
57 if (!GetInstance())
58 g_instance_ = new HungRendererDialogMetro;
11 return g_instance_; 59 return g_instance_;
12 } 60 }
13 61
14 void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) { 62 // static
15 HungRendererDialogView::ShowForWebContents(contents); 63 HungRendererDialogMetro* HungRendererDialogMetro::GetInstance() {
64 return g_instance_;
16 } 65 }
17 66
18 void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) { 67 HungRendererDialogMetro::HungRendererDialogMetro()
19 HungRendererDialogView::EndForWebContents(contents); 68 : contents_(NULL),
69 metro_dialog_displayed_(false) {
20 } 70 }
71
72 HungRendererDialogMetro::~HungRendererDialogMetro() {
73 }
74
75 void HungRendererDialogMetro::Show(WebContents* contents) {
76 if (!metro_dialog_displayed_ &&
77 HungRendererDialogView::IsFrameActive(contents)) {
78 HMODULE metro_dll = base::win::GetMetroModule();
79 DCHECK(metro_dll);
80 if (metro_dll) {
81 MetroShowDialogBox show_dialog_box = reinterpret_cast<MetroShowDialogBox>
82 (::GetProcAddress(metro_dll, "ShowDialogBox"));
83 DCHECK(show_dialog_box);
84 if (show_dialog_box) {
85 string16 dialog_box_title =
86 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
87
88 string16 kill_button_label =
89 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END);
90
91 string16 wait_button_label =
92 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT);
93
94 contents_ = contents;
95 metro_dialog_displayed_ = true;
96
97 (*show_dialog_box)(dialog_box_title.c_str(),
98 contents->GetTitle().c_str(),
99 kill_button_label.c_str(),
100 wait_button_label.c_str(),
101 HungRendererDialogMetro::OnMetroKillProcess,
102 HungRendererDialogMetro::OnMetroWait);
103 }
104 }
105 }
106 }
107
108 void HungRendererDialogMetro::Hide(WebContents* contents) {
109 HMODULE metro_dll = base::win::GetMetroModule();
110 DCHECK(metro_dll);
111 if (metro_dll) {
112 MetroDismissDialogBox dismiss_dialog_box =
113 reinterpret_cast<MetroDismissDialogBox>
114 (::GetProcAddress(metro_dll, "DismissDialogBox"));
115 DCHECK(dismiss_dialog_box);
116 if (dismiss_dialog_box) {
117 (*dismiss_dialog_box)();
118 ResetMetroState();
119 }
120 }
121 }
122
123 void HungRendererDialogMetro::ResetMetroState() {
124 metro_dialog_displayed_ = false;
125 contents_ = NULL;
126 delete g_instance_;
127 g_instance_ = NULL;
sky 2012/07/24 23:40:33 move resetting g_instance_ to the destructor (safe
ananta 2012/07/24 23:45:15 Done.
128 }
129
130 // static
131 void HungRendererDialogMetro::OnMetroKillProcess() {
132 // Metro chrome will invoke these handlers on the metro thread. Ensure that
133 // we switch to the UI thread.
134 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
135 BrowserThread::PostTask(
136 BrowserThread::UI, FROM_HERE,
137 base::Bind(HungRendererDialogMetro::OnMetroKillProcess));
138 return;
139 }
140
141 DCHECK(GetInstance());
sky 2012/07/24 23:40:33 I think you should just return here. I could see t
ananta 2012/07/24 23:45:15 Done.
142 DCHECK(GetInstance()->contents_);
143
144 HungRendererDialogView::KillRendererProcess(
145 GetInstance()->contents_->GetRenderProcessHost()->GetHandle());
146
147 // The metro dialog box is dismissed when the button handlers are invoked.
148 GetInstance()->ResetMetroState();
149 }
150
151 // static
152 void HungRendererDialogMetro::OnMetroWait() {
153 // Metro chrome will invoke these handlers on the metro thread. Ensure that
154 // we switch to the UI thread.
155 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
156 BrowserThread::PostTask(
157 BrowserThread::UI, FROM_HERE,
158 base::Bind(HungRendererDialogMetro::OnMetroWait));
159 return;
160 }
161
162 DCHECK(GetInstance());
sky 2012/07/24 23:40:33 Same comment here, just return if no instance.
ananta 2012/07/24 23:45:15 Done.
163 GetInstance()->ResetMetroState();
164 }
OLDNEW
« 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