diff options
author | whyuan@google.com <whyuan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-20 23:02:29 +0000 |
---|---|---|
committer | whyuan@google.com <whyuan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-20 23:02:29 +0000 |
commit | f62f2c5f990f8636060854cf6b497370725ca3bf (patch) | |
tree | e013c67633f14d7e13b72a28e057c2beaa54a38e /chrome/browser/hang_monitor | |
parent | 4386be59f026d136c0873ca7f83daf49fc613c59 (diff) | |
download | chromium_src-f62f2c5f990f8636060854cf6b497370725ca3bf.zip chromium_src-f62f2c5f990f8636060854cf6b497370725ca3bf.tar.gz chromium_src-f62f2c5f990f8636060854cf6b497370725ca3bf.tar.bz2 |
Log when a browser plugin hangs
Add an API to webplugin_delegate_impl to get the plugin version from the window, similar to the way to get the plugin name. Update hung_plugin_action to log when a browser plugin hangs and log the version of the plugin is Google Talk Plugin.
BUG=
TEST=try bot and manual test on Google Talk Plugin hangs
Review URL: http://codereview.chromium.org/9958104
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133292 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/hang_monitor')
-rw-r--r-- | chrome/browser/hang_monitor/hung_plugin_action.cc | 76 | ||||
-rw-r--r-- | chrome/browser/hang_monitor/hung_plugin_action.h | 11 |
2 files changed, 72 insertions, 15 deletions
diff --git a/chrome/browser/hang_monitor/hung_plugin_action.cc b/chrome/browser/hang_monitor/hung_plugin_action.cc index 57951c9..f8c5606 100644 --- a/chrome/browser/hang_monitor/hung_plugin_action.cc +++ b/chrome/browser/hang_monitor/hung_plugin_action.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,13 +6,56 @@ #include "chrome/browser/hang_monitor/hung_plugin_action.h" +#include "base/metrics/histogram.h" +#include "base/version.h" #include "chrome/browser/simple_message_box.h" #include "chrome/common/logging_chrome.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/win/hwnd_util.h" +#include "webkit/plugins/npapi/plugin_group.h" #include "webkit/plugins/npapi/webplugin_delegate_impl.h" +namespace { + +const wchar_t kGTalkPluginName[] = L"Google Talk Plugin"; +const int kGTalkPluginLogMinVersion = 26; // For version 2.6 and below. + +enum GTalkPluginLogVersion { + GTALK_PLUGIN_VERSION_MIN = 0, + GTALK_PLUGIN_VERSION_27, + GTALK_PLUGIN_VERSION_28, + GTALK_PLUGIN_VERSION_29, + GTALK_PLUGIN_VERSION_30, + GTALK_PLUGIN_VERSION_31, + GTALK_PLUGIN_VERSION_32, + GTALK_PLUGIN_VERSION_33, + GTALK_PLUGIN_VERSION_34, + GTALK_PLUGIN_VERSION_MAX +}; + +// Converts the version string of Google Talk Plugin to a version enum. The +// version format is "major(1 digit).minor(1 digit).sub(1 or 2 digits)", +// for example, "2.7.10" and "2.8.1". Converts the string to a number as +// 10 * major + minor - kGTalkPluginLogMinVersion. +GTalkPluginLogVersion GetGTalkPluginVersion(const string16& version) { + int gtalk_plugin_version = GTALK_PLUGIN_VERSION_MIN; + scoped_ptr<Version> plugin_version( + webkit::npapi::PluginGroup::CreateVersionFromString(version)); + if (plugin_version.get() && plugin_version->components().size() >= 2) { + gtalk_plugin_version = 10 * plugin_version->components()[0] + + plugin_version->components()[1] - kGTalkPluginLogMinVersion; + } + + if (gtalk_plugin_version < GTALK_PLUGIN_VERSION_MIN) + return GTALK_PLUGIN_VERSION_MIN; + if (gtalk_plugin_version > GTALK_PLUGIN_VERSION_MAX) + return GTALK_PLUGIN_VERSION_MAX; + return static_cast<GTalkPluginLogVersion>(gtalk_plugin_version); +} + +} // namespace + HungPluginAction::HungPluginAction() : current_hung_plugin_window_(NULL) { } @@ -38,17 +81,24 @@ bool HungPluginAction::OnHungWindowDetected(HWND hung_window, *action = HungWindowNotification::HUNG_WINDOW_IGNORE; if (top_level_window_process_id != hung_window_process_id) { + string16 plugin_name; + string16 plugin_version; + GetPluginNameAndVersion(hung_window, + top_level_window_process_id, + &plugin_name, + &plugin_version); + if (plugin_name.empty()) { + plugin_name = l10n_util::GetStringUTF16(IDS_UNKNOWN_PLUGIN_NAME); + } else if (kGTalkPluginName == plugin_name) { + UMA_HISTOGRAM_ENUMERATION("GTalkPlugin.Hung", + GetGTalkPluginVersion(plugin_version), + GTALK_PLUGIN_VERSION_MAX + 1); + } + if (logging::DialogsAreSuppressed()) { NOTREACHED() << "Terminated a hung plugin process."; *action = HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS; } else { - string16 plugin_name; - GetPluginName(hung_window, - top_level_window_process_id, - &plugin_name); - if (plugin_name.empty()) { - plugin_name = l10n_util::GetStringUTF16(IDS_UNKNOWN_PLUGIN_NAME); - } string16 msg = l10n_util::GetStringFUTF16(IDS_BROWSER_HANGMONITOR, plugin_name); string16 title = l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_TITLE); @@ -107,10 +157,12 @@ void HungPluginAction::OnWindowResponsive(HWND window) { } } -bool HungPluginAction::GetPluginName(HWND plugin_window, - DWORD browser_process_id, - std::wstring* plugin_name) { +bool HungPluginAction::GetPluginNameAndVersion(HWND plugin_window, + DWORD browser_process_id, + string16* plugin_name, + string16* plugin_version) { DCHECK(plugin_name); + DCHECK(plugin_version); HWND window_to_check = plugin_window; while (NULL != window_to_check) { DWORD process_id = 0; @@ -122,6 +174,8 @@ bool HungPluginAction::GetPluginName(HWND plugin_window, } if (webkit::npapi::WebPluginDelegateImpl::GetPluginNameFromWindow( window_to_check, plugin_name)) { + webkit::npapi::WebPluginDelegateImpl::GetPluginVersionFromWindow( + window_to_check, plugin_version); return true; } window_to_check = GetParent(window_to_check); diff --git a/chrome/browser/hang_monitor/hung_plugin_action.h b/chrome/browser/hang_monitor/hung_plugin_action.h index 4958def..a4b89b9 100644 --- a/chrome/browser/hang_monitor/hung_plugin_action.h +++ b/chrome/browser/hang_monitor/hung_plugin_action.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,7 +6,9 @@ #define CHROME_BROWSER_HANG_MONITOR_HUNG_PLUGIN_ACTION_H__ #pragma once +#include "base/string16.h" #include "chrome/browser/hang_monitor/hung_window_detector.h" + // This class provides an implementation the // HungWindowDetector::HungWindowNotification callback interface. // It checks to see if the hung window belongs to a process different @@ -36,9 +38,10 @@ class HungPluginAction : public HungWindowDetector::HungWindowNotification { static BOOL CALLBACK DismissMessageBox(HWND window, LPARAM ignore); protected: - bool GetPluginName(HWND plugin_window, - DWORD browser_process_id, - std::wstring *plugin_name); + bool GetPluginNameAndVersion(HWND plugin_window, + DWORD browser_process_id, + string16* plugin_name, + string16* plugin_version); // The currently hung plugin window that we are prompting the user about HWND current_hung_plugin_window_; }; |