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