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