NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / views / hung_renderer_view_win.cc
blob992d96497d207163f4ce47b7fae45074c4036100
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/hung_renderer_view_win.h"
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 #include "win8/util/win8_util.h"
16 // Metro functions for displaying and dismissing a dialog box.
17 typedef void (*MetroShowDialogBox)(
18 const wchar_t* title,
19 const wchar_t* content,
20 const wchar_t* button1_label,
21 const wchar_t* button2_label,
22 base::win::MetroDialogButtonPressedHandler button1_handler,
23 base::win::MetroDialogButtonPressedHandler button2_handler);
25 typedef void (*MetroDismissDialogBox)();
27 using content::BrowserThread;
28 using content::WebContents;
30 HungRendererDialogMetro* HungRendererDialogMetro::g_instance_ = NULL;
32 bool PlatformShowCustomHungRendererDialog(WebContents* contents) {
33 if (!win8::IsSingleWindowMetroMode())
34 return false;
36 HungRendererDialogMetro::Create()->Show(contents);
37 return true;
40 bool PlatformHideCustomHungRendererDialog(WebContents* contents) {
41 if (!win8::IsSingleWindowMetroMode())
42 return false;
44 if (HungRendererDialogMetro::GetInstance())
45 HungRendererDialogMetro::GetInstance()->Hide(contents);
46 return true;
49 // static
50 void HungRendererDialogView::KillRendererProcess(
51 base::ProcessHandle process_handle) {
52 // Try to generate a crash report for the hung process.
53 CrashDumpAndTerminateHungChildProcess(process_handle);
56 // static
57 HungRendererDialogMetro* HungRendererDialogMetro::Create() {
58 if (!GetInstance())
59 g_instance_ = new HungRendererDialogMetro;
60 return g_instance_;
63 // static
64 HungRendererDialogMetro* HungRendererDialogMetro::GetInstance() {
65 return g_instance_;
68 HungRendererDialogMetro::HungRendererDialogMetro()
69 : contents_(NULL),
70 metro_dialog_displayed_(false) {
73 HungRendererDialogMetro::~HungRendererDialogMetro() {
74 g_instance_ = NULL;
77 void HungRendererDialogMetro::Show(WebContents* contents) {
78 if (!metro_dialog_displayed_ &&
79 HungRendererDialogView::IsFrameActive(contents)) {
80 HMODULE metro_dll = base::win::GetMetroModule();
81 DCHECK(metro_dll);
82 if (metro_dll) {
83 MetroShowDialogBox show_dialog_box = reinterpret_cast<MetroShowDialogBox>
84 (::GetProcAddress(metro_dll, "ShowDialogBox"));
85 DCHECK(show_dialog_box);
86 if (show_dialog_box) {
87 base::string16 dialog_box_title =
88 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
90 base::string16 kill_button_label =
91 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END);
93 base::string16 wait_button_label =
94 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT);
96 contents_ = contents;
97 metro_dialog_displayed_ = true;
99 (*show_dialog_box)(dialog_box_title.c_str(),
100 contents->GetTitle().c_str(),
101 kill_button_label.c_str(),
102 wait_button_label.c_str(),
103 HungRendererDialogMetro::OnMetroKillProcess,
104 HungRendererDialogMetro::OnMetroWait);
110 void HungRendererDialogMetro::Hide(WebContents* contents) {
111 HMODULE metro_dll = base::win::GetMetroModule();
112 DCHECK(metro_dll);
113 if (metro_dll) {
114 MetroDismissDialogBox dismiss_dialog_box =
115 reinterpret_cast<MetroDismissDialogBox>
116 (::GetProcAddress(metro_dll, "DismissDialogBox"));
117 DCHECK(dismiss_dialog_box);
118 if (dismiss_dialog_box) {
119 (*dismiss_dialog_box)();
120 ResetMetroState();
125 void HungRendererDialogMetro::ResetMetroState() {
126 metro_dialog_displayed_ = false;
127 contents_ = NULL;
128 delete g_instance_;
131 // static
132 void HungRendererDialogMetro::OnMetroKillProcess() {
133 // Metro chrome will invoke these handlers on the metro thread. Ensure that
134 // we switch to the UI thread.
135 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
136 BrowserThread::PostTask(
137 BrowserThread::UI, FROM_HERE,
138 base::Bind(HungRendererDialogMetro::OnMetroKillProcess));
139 return;
142 // Its possible that we got deleted in the meantime.
143 if (!GetInstance())
144 return;
146 DCHECK(GetInstance()->contents_);
148 HungRendererDialogView::KillRendererProcess(
149 GetInstance()->contents_->GetRenderProcessHost()->GetHandle());
151 // The metro dialog box is dismissed when the button handlers are invoked.
152 GetInstance()->ResetMetroState();
155 // static
156 void HungRendererDialogMetro::OnMetroWait() {
157 // Metro chrome will invoke these handlers on the metro thread. Ensure that
158 // we switch to the UI thread.
159 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
160 BrowserThread::PostTask(
161 BrowserThread::UI, FROM_HERE,
162 base::Bind(HungRendererDialogMetro::OnMetroWait));
163 return;
166 // Its possible that we got deleted in the meantime.
167 if (!GetInstance())
168 return;
170 GetInstance()->ResetMetroState();