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 "chrome/browser/plugins/plugin_observer.h" | 5 #include "chrome/browser/plugins/plugin_observer.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/metrics/histogram.h" |
| 10 #include "base/process_util.h" |
9 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
10 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
11 #include "chrome/browser/api/infobars/confirm_infobar_delegate.h" | 13 #include "chrome/browser/api/infobars/confirm_infobar_delegate.h" |
12 #include "chrome/browser/api/infobars/infobar_service.h" | 14 #include "chrome/browser/api/infobars/infobar_service.h" |
13 #include "chrome/browser/api/infobars/simple_alert_infobar_delegate.h" | 15 #include "chrome/browser/api/infobars/simple_alert_infobar_delegate.h" |
14 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/content_settings/host_content_settings_map.h" | 17 #include "chrome/browser/content_settings/host_content_settings_map.h" |
16 #include "chrome/browser/lifetime/application_lifetime.h" | 18 #include "chrome/browser/lifetime/application_lifetime.h" |
17 #include "chrome/browser/metrics/metrics_service.h" | 19 #include "chrome/browser/metrics/metrics_service.h" |
18 #include "chrome/browser/plugins/plugin_finder.h" | 20 #include "chrome/browser/plugins/plugin_finder.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 : content::WebContentsObserver(web_contents), | 176 : content::WebContentsObserver(web_contents), |
175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 177 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
176 } | 178 } |
177 | 179 |
178 PluginObserver::~PluginObserver() { | 180 PluginObserver::~PluginObserver() { |
179 #if defined(ENABLE_PLUGIN_INSTALLATION) | 181 #if defined(ENABLE_PLUGIN_INSTALLATION) |
180 STLDeleteValues(&plugin_placeholders_); | 182 STLDeleteValues(&plugin_placeholders_); |
181 #endif | 183 #endif |
182 } | 184 } |
183 | 185 |
184 void PluginObserver::PluginCrashed(const FilePath& plugin_path) { | 186 void PluginObserver::PluginCrashed(const FilePath& plugin_path, |
| 187 base::ProcessId plugin_pid) { |
185 DCHECK(!plugin_path.value().empty()); | 188 DCHECK(!plugin_path.value().empty()); |
186 | 189 |
187 string16 plugin_name = | 190 string16 plugin_name = |
188 PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path); | 191 PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path); |
| 192 string16 infobar_text; |
| 193 #if defined(OS_WIN) |
| 194 // Find out whether the plugin process is still alive. |
| 195 // Note: Although the chances are slim, it is possible that after the plugin |
| 196 // process died, |plugin_pid| has been reused by a new process. The |
| 197 // consequence is that we will display |IDS_PLUGIN_DISCONNECTED_PROMPT| rather |
| 198 // than |IDS_PLUGIN_CRASHED_PROMPT| to the user, which seems acceptable. |
| 199 base::ProcessHandle plugin_handle = base::kNullProcessHandle; |
| 200 bool open_result = base::OpenProcessHandleWithAccess( |
| 201 plugin_pid, PROCESS_QUERY_INFORMATION | SYNCHRONIZE, &plugin_handle); |
| 202 bool is_running = false; |
| 203 if (open_result) { |
| 204 is_running = base::GetTerminationStatus(plugin_handle, NULL) == |
| 205 base::TERMINATION_STATUS_STILL_RUNNING; |
| 206 base::CloseProcessHandle(plugin_handle); |
| 207 } |
| 208 |
| 209 if (is_running) { |
| 210 infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_DISCONNECTED_PROMPT, |
| 211 plugin_name); |
| 212 UMA_HISTOGRAM_COUNTS("Plugin.ShowDisconnectedInfobar", 1); |
| 213 } else { |
| 214 infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, |
| 215 plugin_name); |
| 216 UMA_HISTOGRAM_COUNTS("Plugin.ShowCrashedInfobar", 1); |
| 217 } |
| 218 #else |
| 219 // Calling the POSIX version of base::GetTerminationStatus() may affect other |
| 220 // code which is interested in the process termination status. (Please see the |
| 221 // comment of the function.) Therefore, a better way is needed to distinguish |
| 222 // disconnections from crashes. |
| 223 infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, |
| 224 plugin_name); |
| 225 UMA_HISTOGRAM_COUNTS("Plugin.ShowCrashedInfobar", 1); |
| 226 #endif |
| 227 |
189 gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 228 gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
190 IDR_INFOBAR_PLUGIN_CRASHED); | 229 IDR_INFOBAR_PLUGIN_CRASHED); |
191 SimpleAlertInfoBarDelegate::Create( | 230 SimpleAlertInfoBarDelegate::Create( |
192 InfoBarService::FromWebContents(web_contents()), icon, | 231 InfoBarService::FromWebContents(web_contents()), icon, infobar_text, |
193 l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, plugin_name), true); | 232 true); |
194 } | 233 } |
195 | 234 |
196 bool PluginObserver::OnMessageReceived(const IPC::Message& message) { | 235 bool PluginObserver::OnMessageReceived(const IPC::Message& message) { |
197 IPC_BEGIN_MESSAGE_MAP(PluginObserver, message) | 236 IPC_BEGIN_MESSAGE_MAP(PluginObserver, message) |
198 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, | 237 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, |
199 OnBlockedOutdatedPlugin) | 238 OnBlockedOutdatedPlugin) |
200 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, | 239 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, |
201 OnBlockedUnauthorizedPlugin) | 240 OnBlockedUnauthorizedPlugin) |
202 #if defined(ENABLE_PLUGIN_INSTALLATION) | 241 #if defined(ENABLE_PLUGIN_INSTALLATION) |
203 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, | 242 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 return; | 387 return; |
349 } | 388 } |
350 | 389 |
351 PluginMetroModeInfoBarDelegate::Create( | 390 PluginMetroModeInfoBarDelegate::Create( |
352 InfoBarService::FromWebContents(web_contents()), | 391 InfoBarService::FromWebContents(web_contents()), |
353 PluginMetroModeInfoBarDelegate::DESKTOP_MODE_REQUIRED, plugin->name()); | 392 PluginMetroModeInfoBarDelegate::DESKTOP_MODE_REQUIRED, plugin->name()); |
354 #else | 393 #else |
355 NOTREACHED(); | 394 NOTREACHED(); |
356 #endif | 395 #endif |
357 } | 396 } |
OLD | NEW |