diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 14:06:42 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 14:06:42 +0000 |
commit | cf4d6e74cc1d992ba263bb635406c24789200fac (patch) | |
tree | 121e274ba7d67cb2bee1d6212db292e6b2b4fd1d /chrome | |
parent | 8d4b16f7f5e3b1faa076e5db16f4e08b80231a0d (diff) | |
download | chromium_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.grd | 3 | ||||
-rw-r--r-- | chrome/browser/plugins/plugin_observer.cc | 45 | ||||
-rw-r--r-- | chrome/browser/plugins/plugin_observer.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/hung_plugin_tab_helper.cc | 3 | ||||
-rw-r--r-- | chrome/browser/ui/hung_plugin_tab_helper.h | 3 |
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; |