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 <windows.h> | 5 #include <windows.h> |
6 | 6 |
7 #include "chrome/browser/hang_monitor/hung_plugin_action.h" | 7 #include "chrome/browser/hang_monitor/hung_plugin_action.h" |
8 | 8 |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/version.h" | 10 #include "base/version.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 76 |
77 DWORD hung_window_process_id = 0; | 77 DWORD hung_window_process_id = 0; |
78 DWORD top_level_window_process_id = 0; | 78 DWORD top_level_window_process_id = 0; |
79 GetWindowThreadProcessId(hung_window, &hung_window_process_id); | 79 GetWindowThreadProcessId(hung_window, &hung_window_process_id); |
80 GetWindowThreadProcessId(top_level_window, &top_level_window_process_id); | 80 GetWindowThreadProcessId(top_level_window, &top_level_window_process_id); |
81 | 81 |
82 *action = HungWindowNotification::HUNG_WINDOW_IGNORE; | 82 *action = HungWindowNotification::HUNG_WINDOW_IGNORE; |
83 if (top_level_window_process_id != hung_window_process_id) { | 83 if (top_level_window_process_id != hung_window_process_id) { |
84 base::string16 plugin_name; | 84 base::string16 plugin_name; |
85 base::string16 plugin_version; | 85 base::string16 plugin_version; |
86 GetPluginNameAndVersion(hung_window, | 86 |
87 top_level_window_process_id, | 87 content::PluginService::GetInstance()->GetPluginInfoFromWindow( |
88 &plugin_name, | 88 hung_window, &plugin_name, &plugin_version); |
89 &plugin_version); | |
90 if (plugin_name.empty()) { | 89 if (plugin_name.empty()) { |
91 plugin_name = l10n_util::GetStringUTF16(IDS_UNKNOWN_PLUGIN_NAME); | 90 plugin_name = l10n_util::GetStringUTF16(IDS_UNKNOWN_PLUGIN_NAME); |
92 } else if (kGTalkPluginName == plugin_name) { | 91 } else if (kGTalkPluginName == plugin_name) { |
93 UMA_HISTOGRAM_ENUMERATION("GTalkPlugin.Hung", | 92 UMA_HISTOGRAM_ENUMERATION("GTalkPlugin.Hung", |
94 GetGTalkPluginVersion(plugin_version), | 93 GetGTalkPluginVersion(plugin_version), |
95 GTALK_PLUGIN_VERSION_MAX + 1); | 94 GTALK_PLUGIN_VERSION_MAX + 1); |
96 } | 95 } |
97 | 96 |
98 if (logging::DialogsAreSuppressed()) { | 97 if (logging::DialogsAreSuppressed()) { |
99 NOTREACHED() << "Terminated a hung plugin process."; | 98 NOTREACHED() << "Terminated a hung plugin process."; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 // The message timeout for this window should fallback to the default | 152 // The message timeout for this window should fallback to the default |
154 // timeout as this window is now responsive. | 153 // timeout as this window is now responsive. |
155 RemoveProp(window, HungWindowDetector::kHungChildWindowTimeout); | 154 RemoveProp(window, HungWindowDetector::kHungChildWindowTimeout); |
156 // The monitored plugin recovered. Let's dismiss the message box. | 155 // The monitored plugin recovered. Let's dismiss the message box. |
157 EnumThreadWindows(GetCurrentThreadId(), | 156 EnumThreadWindows(GetCurrentThreadId(), |
158 reinterpret_cast<WNDENUMPROC>(DismissMessageBox), | 157 reinterpret_cast<WNDENUMPROC>(DismissMessageBox), |
159 NULL); | 158 NULL); |
160 } | 159 } |
161 } | 160 } |
162 | 161 |
163 bool HungPluginAction::GetPluginNameAndVersion(HWND plugin_window, | |
164 DWORD browser_process_id, | |
165 base::string16* plugin_name, | |
166 base::string16* plugin_version) { | |
167 DCHECK(plugin_name); | |
168 DCHECK(plugin_version); | |
169 HWND window_to_check = plugin_window; | |
170 while (NULL != window_to_check) { | |
171 DWORD process_id = 0; | |
172 GetWindowThreadProcessId(window_to_check, &process_id); | |
173 if (process_id == browser_process_id) { | |
174 // If we have reached a window the that belongs to the browser process | |
175 // we have gone too far. | |
176 return false; | |
177 } | |
178 if (content::PluginService::GetInstance()->GetPluginInfoFromWindow( | |
179 window_to_check, plugin_name, plugin_version)) { | |
180 return true; | |
181 } | |
182 window_to_check = GetParent(window_to_check); | |
183 } | |
184 return false; | |
185 } | |
186 | |
187 // static | 162 // static |
188 BOOL CALLBACK HungPluginAction::DismissMessageBox(HWND window, LPARAM ignore) { | 163 BOOL CALLBACK HungPluginAction::DismissMessageBox(HWND window, LPARAM ignore) { |
189 base::string16 class_name = gfx::GetClassName(window); | 164 base::string16 class_name = gfx::GetClassName(window); |
190 // #32770 is the dialog window class which is the window class of | 165 // #32770 is the dialog window class which is the window class of |
191 // the message box being displayed. | 166 // the message box being displayed. |
192 if (class_name == L"#32770") { | 167 if (class_name == L"#32770") { |
193 EndDialog(window, IDNO); | 168 EndDialog(window, IDNO); |
194 return FALSE; | 169 return FALSE; |
195 } | 170 } |
196 return TRUE; | 171 return TRUE; |
197 } | 172 } |
198 | 173 |
199 // static | 174 // static |
200 void CALLBACK HungPluginAction::HungWindowResponseCallback(HWND target_window, | 175 void CALLBACK HungPluginAction::HungWindowResponseCallback(HWND target_window, |
201 UINT message, | 176 UINT message, |
202 ULONG_PTR data, | 177 ULONG_PTR data, |
203 LRESULT result) { | 178 LRESULT result) { |
204 HungPluginAction* instance = reinterpret_cast<HungPluginAction*>(data); | 179 HungPluginAction* instance = reinterpret_cast<HungPluginAction*>(data); |
205 DCHECK(NULL != instance); | 180 DCHECK(NULL != instance); |
206 if (NULL != instance) { | 181 if (NULL != instance) { |
207 instance->OnWindowResponsive(target_window); | 182 instance->OnWindowResponsive(target_window); |
208 } | 183 } |
209 } | 184 } |
OLD | NEW |