Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1075)

Side by Side Diff: chrome/browser/ui/hung_plugin_tab_helper.cc

Issue 297293002: Change HungPluginTabHelper to listen for infobar changes through Observer style. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: observer installed Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/hung_plugin_tab_helper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ui/hung_plugin_tab_helper.h" 5 #include "chrome/browser/ui/hung_plugin_tab_helper.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/process/process.h" 10 #include "base/process/process.h"
11 #include "base/rand_util.h" 11 #include "base/rand_util.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/infobars/infobar_service.h" 13 #include "chrome/browser/infobars/infobar_service.h"
15 #include "chrome/common/chrome_version_info.h" 14 #include "chrome/common/chrome_version_info.h"
16 #include "components/infobars/core/confirm_infobar_delegate.h" 15 #include "components/infobars/core/confirm_infobar_delegate.h"
17 #include "components/infobars/core/infobar.h" 16 #include "components/infobars/core/infobar.h"
18 #include "content/public/browser/browser_child_process_host_iterator.h" 17 #include "content/public/browser/browser_child_process_host_iterator.h"
19 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/child_process_data.h" 19 #include "content/public/browser/child_process_data.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/plugin_service.h" 20 #include "content/public/browser/plugin_service.h"
24 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/render_process_host.h"
25 #include "content/public/common/process_type.h" 22 #include "content/public/common/process_type.h"
26 #include "content/public/common/result_codes.h" 23 #include "content/public/common/result_codes.h"
27 #include "grit/chromium_strings.h" 24 #include "grit/chromium_strings.h"
28 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
29 #include "grit/locale_settings.h" 26 #include "grit/locale_settings.h"
30 #include "grit/theme_resources.h" 27 #include "grit/theme_resources.h"
31 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
32 29
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 251
255 HungPluginTabHelper::PluginState::~PluginState() { 252 HungPluginTabHelper::PluginState::~PluginState() {
256 } 253 }
257 254
258 255
259 // HungPluginTabHelper -------------------------------------------------------- 256 // HungPluginTabHelper --------------------------------------------------------
260 257
261 DEFINE_WEB_CONTENTS_USER_DATA_KEY(HungPluginTabHelper); 258 DEFINE_WEB_CONTENTS_USER_DATA_KEY(HungPluginTabHelper);
262 259
263 HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents) 260 HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents)
264 : content::WebContentsObserver(contents) { 261 : content::WebContentsObserver(contents),
265 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 262 observer_installed_(false) {
266 content::NotificationService::AllSources());
267 } 263 }
268 264
269 HungPluginTabHelper::~HungPluginTabHelper() { 265 HungPluginTabHelper::~HungPluginTabHelper() {
270 } 266 }
271 267
272 void HungPluginTabHelper::PluginCrashed(const base::FilePath& plugin_path, 268 void HungPluginTabHelper::PluginCrashed(const base::FilePath& plugin_path,
273 base::ProcessId plugin_pid) { 269 base::ProcessId plugin_pid) {
274 // TODO(brettw) ideally this would take the child process ID. When we do this 270 // TODO(brettw) ideally this would take the child process ID. When we do this
275 // for NaCl plugins, we'll want to know exactly which process it was since 271 // for NaCl plugins, we'll want to know exactly which process it was since
276 // the path won't be useful. 272 // the path won't be useful.
277 InfoBarService* infobar_service = 273 InfoBarService* infobar_service =
278 InfoBarService::FromWebContents(web_contents()); 274 InfoBarService::FromWebContents(web_contents());
279 if (!infobar_service) 275 if (!infobar_service)
280 return; 276 return;
281 277
278 if (!observer_installed_) {
279 observer_installed_ = true;
280 infobar_service->AddObserver(this);
Peter Kasting 2014/05/30 18:05:48 Why do we want to add an observer here? We don't
281 }
282
282 // For now, just do a brute-force search to see if we have this plugin. Since 283 // For now, just do a brute-force search to see if we have this plugin. Since
283 // we'll normally have 0 or 1, this is fast. 284 // we'll normally have 0 or 1, this is fast.
284 for (PluginStateMap::iterator i = hung_plugins_.begin(); 285 for (PluginStateMap::iterator i = hung_plugins_.begin();
285 i != hung_plugins_.end(); ++i) { 286 i != hung_plugins_.end(); ++i) {
286 if (i->second->path == plugin_path) { 287 if (i->second->path == plugin_path) {
287 if (i->second->infobar) 288 if (i->second->infobar)
288 infobar_service->RemoveInfoBar(i->second->infobar); 289 infobar_service->RemoveInfoBar(i->second->infobar);
289 hung_plugins_.erase(i); 290 hung_plugins_.erase(i);
290 break; 291 break;
291 } 292 }
292 } 293 }
293 } 294 }
294 295
295 void HungPluginTabHelper::PluginHungStatusChanged( 296 void HungPluginTabHelper::PluginHungStatusChanged(
296 int plugin_child_id, 297 int plugin_child_id,
297 const base::FilePath& plugin_path, 298 const base::FilePath& plugin_path,
298 bool is_hung) { 299 bool is_hung) {
299 InfoBarService* infobar_service = 300 InfoBarService* infobar_service =
300 InfoBarService::FromWebContents(web_contents()); 301 InfoBarService::FromWebContents(web_contents());
301 if (!infobar_service) 302 if (!infobar_service)
302 return; 303 return;
303 304
305 if (!observer_installed_) {
306 observer_installed_ = true;
307 infobar_service->AddObserver(this);
Peter Kasting 2014/05/30 18:05:48 Wouldn't we want this in ShowBar() instead of here
308 }
309
304 PluginStateMap::iterator found = hung_plugins_.find(plugin_child_id); 310 PluginStateMap::iterator found = hung_plugins_.find(plugin_child_id);
305 if (found != hung_plugins_.end()) { 311 if (found != hung_plugins_.end()) {
306 if (!is_hung) { 312 if (!is_hung) {
307 // Hung plugin became un-hung, close the infobar and delete our info. 313 // Hung plugin became un-hung, close the infobar and delete our info.
308 if (found->second->infobar) 314 if (found->second->infobar)
309 infobar_service->RemoveInfoBar(found->second->infobar); 315 infobar_service->RemoveInfoBar(found->second->infobar);
310 hung_plugins_.erase(found); 316 hung_plugins_.erase(found);
311 } 317 }
312 return; 318 return;
313 } 319 }
314 320
315 base::string16 plugin_name = 321 base::string16 plugin_name =
316 content::PluginService::GetInstance()->GetPluginDisplayNameByPath( 322 content::PluginService::GetInstance()->GetPluginDisplayNameByPath(
317 plugin_path); 323 plugin_path);
318 324
319 linked_ptr<PluginState> state(new PluginState(plugin_path, plugin_name)); 325 linked_ptr<PluginState> state(new PluginState(plugin_path, plugin_name));
320 hung_plugins_[plugin_child_id] = state; 326 hung_plugins_[plugin_child_id] = state;
321 ShowBar(plugin_child_id, state.get()); 327 ShowBar(plugin_child_id, state.get());
322 } 328 }
323 329
324 void HungPluginTabHelper::Observe(
325 int type,
326 const content::NotificationSource& source,
327 const content::NotificationDetails& details) {
328 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
329 infobars::InfoBar* infobar =
330 content::Details<infobars::InfoBar::RemovedDetails>(details)->first;
331 for (PluginStateMap::iterator i = hung_plugins_.begin();
332 i != hung_plugins_.end(); ++i) {
333 PluginState* state = i->second.get();
334 if (state->infobar == infobar) {
335 state->infobar = NULL;
336
337 // Schedule the timer to re-show the infobar if the plugin continues to be
338 // hung.
339 state->timer.Start(FROM_HERE, state->next_reshow_delay,
340 base::Bind(&HungPluginTabHelper::OnReshowTimer,
341 base::Unretained(this),
342 i->first));
343
344 // Next time we do this, delay it twice as long to avoid being annoying.
345 state->next_reshow_delay *= 2;
346 return;
347 }
348 }
349 }
350
351 void HungPluginTabHelper::KillPlugin(int child_id) { 330 void HungPluginTabHelper::KillPlugin(int child_id) {
352 #if defined(OS_WIN) 331 #if defined(OS_WIN)
353 // Dump renderers that are sending or receiving pepper messages, in order to 332 // Dump renderers that are sending or receiving pepper messages, in order to
354 // diagnose inter-process deadlocks. 333 // diagnose inter-process deadlocks.
355 // Only do that on the Canary channel, for 20% of pepper plugin hangs. 334 // Only do that on the Canary channel, for 20% of pepper plugin hangs.
356 if (base::RandInt(0, 100) < 20) { 335 if (base::RandInt(0, 100) < 20) {
357 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 336 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
358 if (channel == chrome::VersionInfo::CHANNEL_CANARY) { 337 if (channel == chrome::VersionInfo::CHANNEL_CANARY) {
359 scoped_ptr<OwnedHandleVector> renderer_handles(new OwnedHandleVector); 338 scoped_ptr<OwnedHandleVector> renderer_handles(new OwnedHandleVector);
360 HANDLE current_process = ::GetCurrentProcess(); 339 HANDLE current_process = ::GetCurrentProcess();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 394 }
416 395
417 void HungPluginTabHelper::CloseBar(PluginState* state) { 396 void HungPluginTabHelper::CloseBar(PluginState* state) {
418 InfoBarService* infobar_service = 397 InfoBarService* infobar_service =
419 InfoBarService::FromWebContents(web_contents()); 398 InfoBarService::FromWebContents(web_contents());
420 if (infobar_service && state->infobar) { 399 if (infobar_service && state->infobar) {
421 infobar_service->RemoveInfoBar(state->infobar); 400 infobar_service->RemoveInfoBar(state->infobar);
422 state->infobar = NULL; 401 state->infobar = NULL;
423 } 402 }
424 } 403 }
404
405 void HungPluginTabHelper::OnInfoBarRemoved(infobars::InfoBar* infobar,
406 bool animate) {
407 for (PluginStateMap::iterator i = hung_plugins_.begin();
408 i != hung_plugins_.end(); ++i) {
409 PluginState* state = i->second.get();
410 if (state->infobar == infobar) {
411 state->infobar = NULL;
412
413 // Schedule the timer to re-show the infobar if the plugin continues to be
414 // hung.
415 state->timer.Start(FROM_HERE,
416 state->next_reshow_delay,
417 base::Bind(&HungPluginTabHelper::OnReshowTimer,
418 base::Unretained(this),
419 i->first));
420
421 // Next time we do this, delay it twice as long to avoid being annoying.
422 state->next_reshow_delay *= 2;
423 return;
424 }
425 }
426 }
427
428 void HungPluginTabHelper::OnManagerShuttingDown(
429 infobars::InfoBarManager* manager) {
430 InfoBarService* infobar_service =
431 InfoBarService::FromWebContents(web_contents());
432 if (!infobar_service)
433 return;
434
435 if (observer_installed_)
436 infobar_service->RemoveObserver(this);
437 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/hung_plugin_tab_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698