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
21class Browser;
22class GURL;
23class Profile;
24
25namespace content {
26class DevToolsAgentHost;
27class RenderViewHost;
28class SiteInstance;
29};
30
31namespace extensions {
32class Extension;
33class 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.
39class 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