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 #include "base/win/metro.h" | |
8 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h" | |
9 #include "content/public/browser/browser_thread.h" | |
10 #include "content/public/browser/render_process_host.h" | |
11 #include "grit/generated_resources.h" | |
12 #include "ui/base/l10n/l10n_util.h" | |
13 | |
14 // Handler function type. This function is invoked when a button on the metro | |
15 // dialog box is clicked. | |
16 typedef void (*ButtonPressedHandler)(); | |
17 | |
18 // Metro functions for displaying and dismissing a dialog box. | |
19 typedef void (*MetroShowDialogBox)(const wchar_t* title, | |
20 const wchar_t* content, | |
21 const wchar_t* button1_label, | |
22 const wchar_t* button2_label, | |
23 ButtonPressedHandler button1_handler, | |
24 ButtonPressedHandler button2_handler); | |
25 | |
26 typedef void (*MetroDismissDialogBox)(); | |
27 | |
28 using content::BrowserThread; | |
29 | |
7 // static | 30 // static |
8 HungRendererDialogView* HungRendererDialogView::Create() { | 31 HungRendererDialogView* HungRendererDialogView::Create() { |
9 if (!g_instance_) | 32 if (!g_instance_) |
10 g_instance_ = new HungRendererDialogViewWin(); | 33 g_instance_ = new HungRendererDialogViewWin(); |
11 return g_instance_; | 34 return g_instance_; |
12 } | 35 } |
13 | 36 |
37 HungRendererDialogViewWin::HungRendererDialogViewWin() | |
38 : contents_(NULL), | |
39 metro_dialog_displayed_(false) { | |
40 } | |
41 | |
42 HungRendererDialogViewWin::~HungRendererDialogViewWin() { | |
43 } | |
44 | |
14 void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) { | 45 void HungRendererDialogViewWin::ShowForWebContents(WebContents* contents) { |
15 HungRendererDialogView::ShowForWebContents(contents); | 46 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
| |
47 HungRendererDialogView::ShowForWebContents(contents); | |
48 return; | |
49 } | |
50 if (!metro_dialog_displayed_ && IsFrameActive(contents)) { | |
51 HMODULE metro_dll = base::win::GetMetroModule(); | |
52 DCHECK(metro_dll); | |
53 if (metro_dll) { | |
54 MetroShowDialogBox show_dialog_box = reinterpret_cast<MetroShowDialogBox> | |
55 (::GetProcAddress(metro_dll, "ShowDialogBox")); | |
56 DCHECK(show_dialog_box); | |
57 if (show_dialog_box) { | |
58 string16 dialog_box_title = | |
59 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE); | |
60 | |
61 string16 kill_button_label = | |
62 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END); | |
63 | |
64 string16 wait_button_label = | |
65 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); | |
66 | |
67 metro_dialog_displayed_ = true; | |
68 | |
69 (*show_dialog_box)(dialog_box_title.c_str(), | |
70 contents->GetTitle().c_str(), | |
71 kill_button_label.c_str(), | |
72 wait_button_label.c_str(), | |
73 HungRendererDialogViewWin::OnMetroKillProcess, | |
74 HungRendererDialogViewWin::OnMetroWait); | |
75 } | |
76 } | |
77 } | |
16 } | 78 } |
17 | 79 |
18 void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) { | 80 void HungRendererDialogViewWin::EndForWebContents(WebContents* contents) { |
19 HungRendererDialogView::EndForWebContents(contents); | 81 if (!base::win::IsMetroProcess()) { |
82 HungRendererDialogView::EndForWebContents(contents); | |
83 return; | |
84 } | |
85 HMODULE metro_dll = base::win::GetMetroModule(); | |
86 DCHECK(metro_dll); | |
87 if (metro_dll) { | |
88 MetroDismissDialogBox dismiss_dialog_box = | |
89 reinterpret_cast<MetroDismissDialogBox> | |
90 (::GetProcAddress(metro_dll, "DismissDialogBox")); | |
91 DCHECK(dismiss_dialog_box); | |
92 if (dismiss_dialog_box) { | |
93 (*dismiss_dialog_box)(); | |
94 ResetMetroState(); | |
95 } | |
96 } | |
20 } | 97 } |
98 | |
99 void HungRendererDialogViewWin::ResetMetroState() { | |
100 metro_dialog_displayed_ = false; | |
101 contents_ = NULL; | |
102 } | |
103 | |
104 // static | |
105 void HungRendererDialogViewWin::OnMetroKillProcess() { | |
106 // Metro chrome will invoke these handlers on the metro thread. Ensure that | |
107 // we switch to the UI thread. | |
108 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
109 BrowserThread::PostTask( | |
110 BrowserThread::UI, FROM_HERE, | |
111 base::Bind(HungRendererDialogViewWin::OnMetroKillProcess)); | |
112 return; | |
113 } | |
114 | |
115 HungRendererDialogViewWin* instance = | |
116 static_cast<HungRendererDialogViewWin*>(GetInstance()); | |
117 DCHECK(instance); | |
118 DCHECK(instance->contents_); | |
119 | |
120 KillRendererProcess( | |
121 instance->contents_->GetRenderProcessHost()->GetHandle()); | |
122 | |
123 // The metro dialog box is dismissed when the button handlers are invoked. | |
124 instance->ResetMetroState(); | |
125 } | |
126 | |
127 // static | |
128 void HungRendererDialogViewWin::OnMetroWait() { | |
129 // Metro chrome will invoke these handlers on the metro thread. Ensure that | |
130 // we switch to the UI thread. | |
131 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
132 BrowserThread::PostTask( | |
133 BrowserThread::UI, FROM_HERE, | |
134 base::Bind(HungRendererDialogViewWin::OnMetroWait)); | |
135 return; | |
136 } | |
137 HungRendererDialogViewWin* instance = | |
138 static_cast<HungRendererDialogViewWin*>(GetInstance()); | |
139 DCHECK(instance); | |
140 instance->ResetMetroState(); | |
141 } | |
142 | |
143 // static | |
144 void HungRendererDialogView::KillRendererProcess( | |
145 base::ProcessHandle process_handle) { | |
146 // Try to generate a crash report for the hung process. | |
147 CrashDumpAndTerminateHungChildProcess(process_handle); | |
148 } | |
OLD | NEW |