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