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 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