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