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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_HUNG_PLUGIN_TAB_HELPER_H_ 6 #define CHROME_BROWSER_UI_HUNG_PLUGIN_TAB_HELPER_H_ 7 8 #include <map> 9 10 #include "base/memory/linked_ptr.h" 11 #include "base/strings/string16.h" 12 #include "base/time/time.h" 13 #include "base/timer/timer.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 #include "content/public/browser/web_contents_observer.h" 17 #include "content/public/browser/web_contents_user_data.h" 18 19 class InfoBarDelegate; 20 21 namespace base { 22 class FilePath; 23 } 24 25 // Manages per-tab state with regard to hung plugins. This only handles 26 // Pepper plugins which we know are windowless. Hung NPAPI plugins (which 27 // may have native windows) can not be handled with infobars and have a 28 // separate OS-specific hang monitoring. 29 // 30 // Our job is: 31 // - Pop up an infobar when a plugin is hung. 32 // - Terminate the plugin process if the user so chooses. 33 // - Periodically re-show the hung plugin infobar if the user closes it without 34 // terminating the plugin. 35 // - Hide the infobar if the plugin starts responding again. 36 // - Keep track of all of this for any number of plugins. 37 class HungPluginTabHelper 38 : public content::WebContentsObserver, 39 public content::NotificationObserver, 40 public content::WebContentsUserData<HungPluginTabHelper> { 41 public: 42 virtual ~HungPluginTabHelper(); 43 44 // content::WebContentsObserver: 45 virtual void PluginCrashed(const base::FilePath& plugin_path, 46 base::ProcessId plugin_pid) OVERRIDE; 47 virtual void PluginHungStatusChanged(int plugin_child_id, 48 const base::FilePath& plugin_path, 49 bool is_hung) OVERRIDE; 50 51 // content::NotificationObserver: 52 virtual void Observe(int type, 53 const content::NotificationSource& source, 54 const content::NotificationDetails& details) OVERRIDE; 55 56 // Called by an infobar when the user selects to kill the plugin. 57 void KillPlugin(int child_id); 58 59 private: 60 friend class content::WebContentsUserData<HungPluginTabHelper>; 61 62 struct PluginState; 63 typedef std::map<int, linked_ptr<PluginState> > PluginStateMap; 64 65 explicit HungPluginTabHelper(content::WebContents* contents); 66 67 // Called on a timer for a hung plugin to re-show the bar. 68 void OnReshowTimer(int child_id); 69 70 // Shows the bar for the plugin identified by the given state, updating the 71 // state accordingly. The plugin must not have an infobar already. 72 void ShowBar(int child_id, PluginState* state); 73 74 // Closes the infobar associated with the given state. Note that this can 75 // be called even if the bar is not opened, in which case it will do nothing. 76 void CloseBar(PluginState* state); 77 78 content::NotificationRegistrar registrar_; 79 80 // All currently hung plugins. 81 PluginStateMap hung_plugins_; 82 83 DISALLOW_COPY_AND_ASSIGN(HungPluginTabHelper); 84 }; 85 86 #endif // CHROME_BROWSER_UI_HUNG_PLUGIN_TAB_HELPER_H_ 87