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_win.h" | 5 #include "chrome/browser/ui/views/hung_renderer_view_win.h" |
6 | 6 |
7 // static | 7 #include "base/win/metro.h" |
8 HungRendererDialogView* HungRendererDialogView::Create() { | 8 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h" |
9 if (!g_instance_) | 9 #include "chrome/browser/ui/views/hung_renderer_view.h" |
10 g_instance_ = new HungRendererDialogViewWin(); | 10 #include "content/public/browser/browser_thread.h" |
11 return g_instance_; | 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 | |
28 static HungRendererDialogMetro g_instance; | |
sky
2012/07/24 21:26:05
Static types can't be objects.
ananta
2012/07/24 21:36:17
Done.
| |
29 | |
30 bool PlatformShowCustomHungRendererDialog(WebContents* contents) { | |
31 if (!base::win::IsMetroProcess()) | |
32 return false; | |
33 g_instance.Show(contents); | |
34 return true; | |
12 } | 35 } |
13 | 36 |
14 void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) { | 37 bool PlatformHideCustomHungRendererDialog(WebContents* contents) { |
15 HungRendererDialogView::ShowForWebContents(contents); | 38 if (!base::win::IsMetroProcess()) |
39 return false; | |
40 g_instance.Hide(contents); | |
41 return true; | |
16 } | 42 } |
17 | 43 |
18 void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) { | 44 // static |
19 HungRendererDialogView::EndForWebContents(contents); | 45 void HungRendererDialogView::KillRendererProcess( |
46 base::ProcessHandle process_handle) { | |
47 // Try to generate a crash report for the hung process. | |
48 CrashDumpAndTerminateHungChildProcess(process_handle); | |
20 } | 49 } |
50 | |
51 HungRendererDialogMetro::HungRendererDialogMetro() | |
52 : contents_(NULL), | |
53 metro_dialog_displayed_(false) { | |
54 } | |
55 | |
56 HungRendererDialogMetro::~HungRendererDialogMetro() { | |
57 } | |
58 | |
59 void HungRendererDialogMetro::Show(WebContents* contents) { | |
60 if (!metro_dialog_displayed_ && | |
61 HungRendererDialogView::IsFrameActive(contents)) { | |
62 HMODULE metro_dll = base::win::GetMetroModule(); | |
63 DCHECK(metro_dll); | |
64 if (metro_dll) { | |
65 MetroShowDialogBox show_dialog_box = reinterpret_cast<MetroShowDialogBox> | |
66 (::GetProcAddress(metro_dll, "ShowDialogBox")); | |
67 DCHECK(show_dialog_box); | |
68 if (show_dialog_box) { | |
69 string16 dialog_box_title = | |
70 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE); | |
71 | |
72 string16 kill_button_label = | |
73 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END); | |
74 | |
75 string16 wait_button_label = | |
76 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); | |
77 | |
78 g_instance.contents_ = contents; | |
79 metro_dialog_displayed_ = true; | |
80 | |
81 (*show_dialog_box)(dialog_box_title.c_str(), | |
82 contents->GetTitle().c_str(), | |
83 kill_button_label.c_str(), | |
84 wait_button_label.c_str(), | |
85 HungRendererDialogMetro::OnMetroKillProcess, | |
86 HungRendererDialogMetro::OnMetroWait); | |
87 } | |
88 } | |
89 } | |
90 } | |
91 | |
92 void HungRendererDialogMetro::Hide(WebContents* contents) { | |
93 HMODULE metro_dll = base::win::GetMetroModule(); | |
94 DCHECK(metro_dll); | |
95 if (metro_dll) { | |
96 MetroDismissDialogBox dismiss_dialog_box = | |
97 reinterpret_cast<MetroDismissDialogBox> | |
98 (::GetProcAddress(metro_dll, "DismissDialogBox")); | |
99 DCHECK(dismiss_dialog_box); | |
100 if (dismiss_dialog_box) { | |
101 (*dismiss_dialog_box)(); | |
102 ResetMetroState(); | |
103 } | |
104 } | |
105 } | |
106 | |
107 void HungRendererDialogMetro::ResetMetroState() { | |
108 metro_dialog_displayed_ = false; | |
109 contents_ = NULL; | |
110 } | |
111 | |
112 // static | |
113 void HungRendererDialogMetro::OnMetroKillProcess() { | |
114 // Metro chrome will invoke these handlers on the metro thread. Ensure that | |
115 // we switch to the UI thread. | |
116 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
117 BrowserThread::PostTask( | |
118 BrowserThread::UI, FROM_HERE, | |
119 base::Bind(HungRendererDialogMetro::OnMetroKillProcess)); | |
120 return; | |
121 } | |
122 | |
123 DCHECK(g_instance.contents_); | |
124 | |
125 HungRendererDialogView::KillRendererProcess( | |
126 g_instance.contents_->GetRenderProcessHost()->GetHandle()); | |
127 | |
128 // The metro dialog box is dismissed when the button handlers are invoked. | |
129 g_instance.ResetMetroState(); | |
130 } | |
131 | |
132 // static | |
133 void HungRendererDialogMetro::OnMetroWait() { | |
134 // Metro chrome will invoke these handlers on the metro thread. Ensure that | |
135 // we switch to the UI thread. | |
136 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
137 BrowserThread::PostTask( | |
138 BrowserThread::UI, FROM_HERE, | |
139 base::Bind(HungRendererDialogMetro::OnMetroWait)); | |
sky
2012/07/24 21:26:05
This is dangerous. How do you know another Show ha
ananta
2012/07/24 21:36:17
The metro_dialog_displayed_ Boolean flag prevents
| |
140 return; | |
141 } | |
142 | |
143 g_instance.ResetMetroState(); | |
144 } | |
OLD | NEW |