summaryrefslogtreecommitdiffstats
path: root/chrome/browser/hang_monitor
diff options
context:
space:
mode:
authorwhyuan@google.com <whyuan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-20 23:02:29 +0000
committerwhyuan@google.com <whyuan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-20 23:02:29 +0000
commitf62f2c5f990f8636060854cf6b497370725ca3bf (patch)
treee013c67633f14d7e13b72a28e057c2beaa54a38e /chrome/browser/hang_monitor
parent4386be59f026d136c0873ca7f83daf49fc613c59 (diff)
downloadchromium_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.cc76
-rw-r--r--chrome/browser/hang_monitor/hung_plugin_action.h11
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_;
};