summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 14:06:42 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 14:06:42 +0000
commitcf4d6e74cc1d992ba263bb635406c24789200fac (patch)
tree121e274ba7d67cb2bee1d6212db292e6b2b4fd1d /chrome
parent8d4b16f7f5e3b1faa076e5db16f4e08b80231a0d (diff)
downloadchromium_src-cf4d6e74cc1d992ba263bb635406c24789200fac.zip
chromium_src-cf4d6e74cc1d992ba263bb635406c24789200fac.tar.gz
chromium_src-cf4d6e74cc1d992ba263bb635406c24789200fac.tar.bz2
Distinguish plugin disconnections from plugin crashes.
If the channel between a renderer and a plugin encounters an error, currently we display an infobar saying "<plugin_name> has crashed.". This may cause confusion, because the plugin process may still be alive and no crash dump is generated in that case. With this CL, we display a different prompt if the plugin process is still alive: "<plugin_name> has encountered an error." This CL only affects Windows. TEST=None BUG=None Review URL: https://chromiumcodereview.appspot.com/11820009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176060 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/plugins/plugin_observer.cc45
-rw-r--r--chrome/browser/plugins/plugin_observer.h3
-rw-r--r--chrome/browser/ui/hung_plugin_tab_helper.cc3
-rw-r--r--chrome/browser/ui/hung_plugin_tab_helper.h3
5 files changed, 51 insertions, 6 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6a7b0e9..0270f12 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12121,6 +12121,9 @@ experiment id: "<ph name="EXPERIMENT_ID">$5<ex>ar1</ex></ph>"
<message name="IDS_PLUGIN_CRASHED_PROMPT" desc="Info Bar message to notify about a crashed plugin">
<ph name="PLUGIN_NAME">$1<ex>Shockwave</ex> has crashed.</ph>
</message>
+ <message name="IDS_PLUGIN_DISCONNECTED_PROMPT" desc="Info Bar message to notify that the channel connecting to a plugin has encountered an error.">
+ <ph name="PLUGIN_NAME">$1<ex>Shockwave</ex> has encountered an error.</ph>
+ </message>
<message name="IDS_PLUGIN_INITIALIZATION_ERROR_PROMPT" desc="Info Bar message to notify that we couldn't load a plugin">
Could not load <ph name="PLUGIN_NAME">$1<ex>Shockwave</ex>.</ph>
</message>
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc
index 750812a..18a902b 100644
--- a/chrome/browser/plugins/plugin_observer.cc
+++ b/chrome/browser/plugins/plugin_observer.cc
@@ -6,6 +6,8 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/metrics/histogram.h"
+#include "base/process_util.h"
#include "base/stl_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/api/infobars/confirm_infobar_delegate.h"
@@ -181,16 +183,53 @@ PluginObserver::~PluginObserver() {
#endif
}
-void PluginObserver::PluginCrashed(const FilePath& plugin_path) {
+void PluginObserver::PluginCrashed(const FilePath& plugin_path,
+ base::ProcessId plugin_pid) {
DCHECK(!plugin_path.value().empty());
string16 plugin_name =
PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path);
+ string16 infobar_text;
+#if defined(OS_WIN)
+ // Find out whether the plugin process is still alive.
+ // Note: Although the chances are slim, it is possible that after the plugin
+ // process died, |plugin_pid| has been reused by a new process. The
+ // consequence is that we will display |IDS_PLUGIN_DISCONNECTED_PROMPT| rather
+ // than |IDS_PLUGIN_CRASHED_PROMPT| to the user, which seems acceptable.
+ base::ProcessHandle plugin_handle = base::kNullProcessHandle;
+ bool open_result = base::OpenProcessHandleWithAccess(
+ plugin_pid, PROCESS_QUERY_INFORMATION | SYNCHRONIZE, &plugin_handle);
+ bool is_running = false;
+ if (open_result) {
+ is_running = base::GetTerminationStatus(plugin_handle, NULL) ==
+ base::TERMINATION_STATUS_STILL_RUNNING;
+ base::CloseProcessHandle(plugin_handle);
+ }
+
+ if (is_running) {
+ infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_DISCONNECTED_PROMPT,
+ plugin_name);
+ UMA_HISTOGRAM_COUNTS("Plugin.ShowDisconnectedInfobar", 1);
+ } else {
+ infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT,
+ plugin_name);
+ UMA_HISTOGRAM_COUNTS("Plugin.ShowCrashedInfobar", 1);
+ }
+#else
+ // Calling the POSIX version of base::GetTerminationStatus() may affect other
+ // code which is interested in the process termination status. (Please see the
+ // comment of the function.) Therefore, a better way is needed to distinguish
+ // disconnections from crashes.
+ infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT,
+ plugin_name);
+ UMA_HISTOGRAM_COUNTS("Plugin.ShowCrashedInfobar", 1);
+#endif
+
gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
IDR_INFOBAR_PLUGIN_CRASHED);
SimpleAlertInfoBarDelegate::Create(
- InfoBarService::FromWebContents(web_contents()), icon,
- l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, plugin_name), true);
+ InfoBarService::FromWebContents(web_contents()), icon, infobar_text,
+ true);
}
bool PluginObserver::OnMessageReceived(const IPC::Message& message) {
diff --git a/chrome/browser/plugins/plugin_observer.h b/chrome/browser/plugins/plugin_observer.h
index e89a327..8fde0ad 100644
--- a/chrome/browser/plugins/plugin_observer.h
+++ b/chrome/browser/plugins/plugin_observer.h
@@ -34,7 +34,8 @@ class PluginObserver : public content::WebContentsObserver,
virtual ~PluginObserver();
// content::WebContentsObserver implementation.
- virtual void PluginCrashed(const FilePath& plugin_path) OVERRIDE;
+ virtual void PluginCrashed(const FilePath& plugin_path,
+ base::ProcessId plugin_pid) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index 2463be4..e04f7cf 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -229,7 +229,8 @@ HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents)
HungPluginTabHelper::~HungPluginTabHelper() {
}
-void HungPluginTabHelper::PluginCrashed(const FilePath& plugin_path) {
+void HungPluginTabHelper::PluginCrashed(const FilePath& plugin_path,
+ base::ProcessId plugin_pid) {
// TODO(brettw) ideally this would take the child process ID. When we do this
// for NaCl plugins, we'll want to know exactly which process it was since
// the path won't be useful.
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.h b/chrome/browser/ui/hung_plugin_tab_helper.h
index 92b9508..0cf6b336 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.h
+++ b/chrome/browser/ui/hung_plugin_tab_helper.h
@@ -40,7 +40,8 @@ class HungPluginTabHelper
virtual ~HungPluginTabHelper();
// content::WebContentsObserver overrides:
- virtual void PluginCrashed(const FilePath& plugin_path) OVERRIDE;
+ virtual void PluginCrashed(const FilePath& plugin_path,
+ base::ProcessId plugin_pid) OVERRIDE;
virtual void PluginHungStatusChanged(int plugin_child_id,
const FilePath& plugin_path,
bool is_hung) OVERRIDE;