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