Home | History | Annotate | Download | only in extensions
      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_EXTENSIONS_EXTENSION_PROCESS_MANAGER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESS_MANAGER_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 
     12 #include "base/callback.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/time/time.h"
     17 #include "content/public/browser/notification_observer.h"
     18 #include "content/public/browser/notification_registrar.h"
     19 #include "extensions/common/view_type.h"
     20 
     21 class Browser;
     22 class GURL;
     23 class Profile;
     24 
     25 namespace content {
     26 class DevToolsAgentHost;
     27 class RenderViewHost;
     28 class SiteInstance;
     29 };
     30 
     31 namespace extensions {
     32 class Extension;
     33 class ExtensionHost;
     34 }
     35 
     36 // Manages dynamic state of running Chromium extensions. There is one instance
     37 // of this class per Profile. OTR Profiles have a separate instance that keeps
     38 // track of split-mode extensions only.
     39 class ExtensionProcessManager : public content::NotificationObserver {
     40  public:
     41   typedef std::set<extensions::ExtensionHost*> ExtensionHostSet;
     42   typedef ExtensionHostSet::const_iterator const_iterator;
     43 
     44   static ExtensionProcessManager* Create(Profile* profile);
     45   virtual ~ExtensionProcessManager();
     46 
     47   const ExtensionHostSet& background_hosts() const {
     48     return background_hosts_;
     49   }
     50 
     51   typedef std::set<content::RenderViewHost*> ViewSet;
     52   const ViewSet GetAllViews() const;
     53 
     54   // Creates a new ExtensionHost with its associated view, grouping it in the
     55   // appropriate SiteInstance (and therefore process) based on the URL and
     56   // profile.
     57   virtual extensions::ExtensionHost* CreateViewHost(
     58       const extensions::Extension* extension,
     59       const GURL& url,
     60       Browser* browser,
     61       extensions::ViewType view_type);
     62   extensions::ExtensionHost* CreateViewHost(const GURL& url,
     63                                             Browser* browser,
     64                                             extensions::ViewType view_type);
     65   extensions::ExtensionHost* CreatePopupHost(
     66       const extensions::Extension* extension,
     67       const GURL& url,
     68       Browser* browser);
     69   extensions::ExtensionHost* CreatePopupHost(const GURL& url, Browser* browser);
     70   extensions::ExtensionHost* CreateDialogHost(const GURL& url);
     71   extensions::ExtensionHost* CreateInfobarHost(
     72       const extensions::Extension* extension,
     73       const GURL& url,
     74       Browser* browser);
     75   extensions::ExtensionHost* CreateInfobarHost(const GURL& url,
     76                                                Browser* browser);
     77 
     78   // Creates a new UI-less extension instance.  Like CreateViewHost, but not
     79   // displayed anywhere.
     80   virtual void CreateBackgroundHost(const extensions::Extension* extension,
     81                                     const GURL& url);
     82 
     83   // Gets the ExtensionHost for the background page for an extension, or NULL if
     84   // the extension isn't running or doesn't have a background page.
     85   extensions::ExtensionHost* GetBackgroundHostForExtension(
     86       const std::string& extension_id);
     87 
     88   // Returns the SiteInstance that the given URL belongs to.
     89   // TODO(aa): This only returns correct results for extensions and packaged
     90   // apps, not hosted apps.
     91   virtual content::SiteInstance* GetSiteInstanceForURL(const GURL& url);
     92 
     93   // Unregisters a RenderViewHost as hosting any extension.
     94   void UnregisterRenderViewHost(content::RenderViewHost* render_view_host);
     95 
     96   // Returns all RenderViewHosts that are registered for the specified
     97   // extension.
     98   std::set<content::RenderViewHost*> GetRenderViewHostsForExtension(
     99       const std::string& extension_id);
    100 
    101   // Returns the extension associated with the specified RenderViewHost, or
    102   // NULL.
    103   const extensions::Extension* GetExtensionForRenderViewHost(
    104       content::RenderViewHost* render_view_host);
    105 
    106   // Returns true if the (lazy) background host for the given extension has
    107   // already been sent the unload event and is shutting down.
    108   bool IsBackgroundHostClosing(const std::string& extension_id);
    109 
    110   // Getter and setter for the lazy background page's keepalive count. This is
    111   // the count of how many outstanding "things" are keeping the page alive.
    112   // When this reaches 0, we will begin the process of shutting down the page.
    113   // "Things" include pending events, resource loads, and API calls.
    114   int GetLazyKeepaliveCount(const extensions::Extension* extension);
    115   int IncrementLazyKeepaliveCount(const extensions::Extension* extension);
    116   int DecrementLazyKeepaliveCount(const extensions::Extension* extension);
    117 
    118   void IncrementLazyKeepaliveCountForView(
    119       content::RenderViewHost* render_view_host);
    120 
    121   // Handles a response to the ShouldSuspend message, used for lazy background
    122   // pages.
    123   void OnShouldSuspendAck(const std::string& extension_id, int sequence_id);
    124 
    125   // Same as above, for the Suspend message.
    126   void OnSuspendAck(const std::string& extension_id);
    127 
    128   // Tracks network requests for a given RenderViewHost, used to know
    129   // when network activity is idle for lazy background pages.
    130   void OnNetworkRequestStarted(content::RenderViewHost* render_view_host);
    131   void OnNetworkRequestDone(content::RenderViewHost* render_view_host);
    132 
    133   // Prevents |extension|'s background page from being closed and sends the
    134   // onSuspendCanceled() event to it.
    135   void CancelSuspend(const extensions::Extension* extension);
    136 
    137  protected:
    138   explicit ExtensionProcessManager(Profile* profile);
    139 
    140   // Called just after |host| is created so it can be registered in our lists.
    141   void OnExtensionHostCreated(extensions::ExtensionHost* host,
    142                               bool is_background);
    143 
    144   // Called on browser shutdown to close our extension hosts.
    145   void CloseBackgroundHosts();
    146 
    147   // content::NotificationObserver:
    148   virtual void Observe(int type,
    149                        const content::NotificationSource& source,
    150                        const content::NotificationDetails& details) OVERRIDE;
    151 
    152   // Load all background pages once the profile data is ready and the pages
    153   // should be loaded.
    154   void CreateBackgroundHostsForProfileStartup();
    155 
    156   // Gets the profile associated with site_instance_ and all other
    157   // related SiteInstances.
    158   Profile* GetProfile() const;
    159 
    160   content::NotificationRegistrar registrar_;
    161 
    162   // The set of ExtensionHosts running viewless background extensions.
    163   ExtensionHostSet background_hosts_;
    164 
    165   // A SiteInstance related to the SiteInstance for all extensions in
    166   // this profile.  We create it in such a way that a new
    167   // browsing instance is created.  This controls process grouping.
    168   scoped_refptr<content::SiteInstance> site_instance_;
    169 
    170  private:
    171   // Extra information we keep for each extension's background page.
    172   struct BackgroundPageData;
    173   typedef std::string ExtensionId;
    174   typedef std::map<ExtensionId, BackgroundPageData> BackgroundPageDataMap;
    175   typedef std::map<content::RenderViewHost*,
    176       extensions::ViewType> ExtensionRenderViews;
    177 
    178   // Close the given |host| iff it's a background page.
    179   void CloseBackgroundHost(extensions::ExtensionHost* host);
    180 
    181   // Ensure browser object is not null except for certain situations.
    182   void EnsureBrowserWhenRequired(Browser* browser,
    183                                  extensions::ViewType view_type);
    184 
    185   // These are called when the extension transitions between idle and active.
    186   // They control the process of closing the background page when idle.
    187   void OnLazyBackgroundPageIdle(const std::string& extension_id,
    188                                 int sequence_id);
    189   void OnLazyBackgroundPageActive(const std::string& extension_id);
    190   void CloseLazyBackgroundPageNow(const std::string& extension_id,
    191                                   int sequence_id);
    192 
    193   // Potentially registers a RenderViewHost, if it is associated with an
    194   // extension. Does nothing if this is not an extension renderer.
    195   void RegisterRenderViewHost(content::RenderViewHost* render_view_host);
    196 
    197   // Clears background page data for this extension.
    198   void ClearBackgroundPageData(const std::string& extension_id);
    199 
    200   // Returns true if loading background pages should be deferred. This is
    201   // true if there are no browser windows open and the browser process was
    202   // started to show the app launcher.
    203   bool DeferLoadingBackgroundHosts() const;
    204 
    205   void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);
    206 
    207   // Contains all active extension-related RenderViewHost instances for all
    208   // extensions. We also keep a cache of the host's view type, because that
    209   // information is not accessible at registration/deregistration time.
    210   ExtensionRenderViews all_extension_views_;
    211 
    212   BackgroundPageDataMap background_page_data_;
    213 
    214   // The time to delay between an extension becoming idle and
    215   // sending a ShouldSuspend message; read from command-line switch.
    216   base::TimeDelta event_page_idle_time_;
    217 
    218   // The time to delay between sending a ShouldSuspend message and
    219   // sending a Suspend message; read from command-line switch.
    220   base::TimeDelta event_page_suspending_time_;
    221 
    222   base::WeakPtrFactory<ExtensionProcessManager> weak_ptr_factory_;
    223 
    224   base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
    225 
    226   DISALLOW_COPY_AND_ASSIGN(ExtensionProcessManager);
    227 };
    228 
    229 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESS_MANAGER_H_
    230