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.
5 #ifndef CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
6 #define CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
8 #include "base/basictypes.h"
9 #include "base/memory/ref_counted.h"
10 #include "content/common/content_export.h"
15 class RenderProcessHost
;
17 ///////////////////////////////////////////////////////////////////////////////
18 // SiteInstance interface.
20 // A SiteInstance represents a group of web pages that must live in the same
21 // renderer process. Pages able to synchronously script each other will always
22 // be placed in the same SiteInstance. Pages unable to synchronously script
23 // each other may also be placed in the same SiteInstance, as determined by the
26 // A page's SiteInstance is determined by a combination of where the page comes
27 // from (the site) and which frames have references to each other (the
28 // instance). Here, a "site" is similar to the page's origin but includes only
29 // the registered domain name and scheme, not the port or subdomains. This
30 // accounts for the fact that changes to document.domain allow similar origin
31 // pages with different ports or subdomains to script each other. An "instance"
32 // includes all frames that might be able to script each other because of how
33 // they were created (e.g., window.open or targeted links). We represent
34 // instances using the BrowsingInstance class.
36 // Four process models are currently supported:
38 // PROCESS PER SITE INSTANCE (the current default): SiteInstances are created
39 // (1) when the user manually creates a new tab (which also creates a new
40 // BrowsingInstance), and (2) when the user navigates across site boundaries
41 // (which uses the same BrowsingInstance). If the user navigates within a site,
42 // the same SiteInstance is used. Caveat: we currently allow renderer-initiated
43 // cross-site navigations to stay in the same SiteInstance, to preserve
44 // compatibility in cases like cross-site iframes that open popups.
46 // SITE PER PROCESS (currently experimental): is the most granular process
47 // model and is made possible by our support for out-of-process iframes. A
48 // subframe will be given a different SiteInstance if its site differs from the
49 // containing document. Cross-site navigation of top-level frames or subframes
50 // will trigger a change of SiteInstances, even if the navigation is renderer
51 // initiated. In this model, each process can be dedicated to documents from
52 // just one site, allowing the same origin policy to be enforced by the sandbox.
54 // PROCESS PER TAB: SiteInstances are created when the user manually creates a
55 // new tab, but not when navigating across site boundaries (unless a process
56 // swap is required for security reasons, such as navigating from a privileged
57 // WebUI page to a normal web page). This corresponds to one process per
60 // PROCESS PER SITE: We consolidate all SiteInstances for a given site into the
61 // same process, throughout the entire browser context. This ensures that only
62 // one process will be used for each site.
64 // Each NavigationEntry for a WebContents points to the SiteInstance that
65 // rendered it. Each RenderFrameHost also points to the SiteInstance that it is
66 // associated with. A SiteInstance keeps track of the number of these
67 // references and deletes itself when the count goes to zero. This means that
68 // a SiteInstance is only live as long as it is accessible, either from new
69 // tabs with no NavigationEntries or in NavigationEntries in the history.
71 ///////////////////////////////////////////////////////////////////////////////
72 class CONTENT_EXPORT SiteInstance
: public base::RefCounted
<SiteInstance
> {
74 // Returns a unique ID for this SiteInstance.
75 virtual int32
GetId() = 0;
77 // Whether this SiteInstance has a running process associated with it.
78 // This may return true before the first call to GetProcess(), in cases where
79 // we use process-per-site and there is an existing process available.
80 virtual bool HasProcess() const = 0;
82 // Returns the current RenderProcessHost being used to render pages for this
83 // SiteInstance. If there is no RenderProcessHost (because either none has
84 // yet been created or there was one but it was cleanly destroyed (e.g. when
85 // it is not actively being used)), then this method will create a new
86 // RenderProcessHost (and a new ID). Note that renderer process crashes leave
87 // the current RenderProcessHost (and ID) in place.
89 // For sites that require process-per-site mode (e.g., WebUI), this will
90 // ensure only one RenderProcessHost for the site exists/ within the
92 virtual content::RenderProcessHost
* GetProcess() = 0;
94 // Browser context to which this SiteInstance (and all related
95 // SiteInstances) belongs.
96 virtual content::BrowserContext
* GetBrowserContext() const = 0;
98 // Get the web site that this SiteInstance is rendering pages for.
99 // This includes the scheme and registered domain, but not the port.
100 virtual const GURL
& GetSiteURL() const = 0;
102 // Gets a SiteInstance for the given URL that shares the current
103 // BrowsingInstance, creating a new SiteInstance if necessary. This ensures
104 // that a BrowsingInstance only has one SiteInstance per site, so that pages
105 // in a BrowsingInstance have the ability to script each other. Callers
106 // should ensure that this SiteInstance becomes ref counted, by storing it in
107 // a scoped_refptr. (By having this method, we can hide the BrowsingInstance
108 // class from the rest of the codebase.)
109 // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
111 virtual SiteInstance
* GetRelatedSiteInstance(const GURL
& url
) = 0;
113 // Returns whether the given SiteInstance is in the same BrowsingInstance as
114 // this one. If so, JavaScript interactions that are permitted across
115 // origins (e.g., postMessage) should be supported.
116 virtual bool IsRelatedSiteInstance(const SiteInstance
* instance
) = 0;
118 // Returns the total active WebContents count for this SiteInstance and all
119 // related SiteInstances in the same BrowsingInstance.
120 virtual size_t GetRelatedActiveContentsCount() = 0;
122 // Returns true if this SiteInstance is for a site that requires a dedicated
123 // process. This only returns true under the "site per process" process model.
124 virtual bool RequiresDedicatedProcess() = 0;
126 // Factory method to create a new SiteInstance. This will create a new
127 // new BrowsingInstance, so it should only be used when creating a new tab
128 // from scratch (or similar circumstances). Callers should ensure that
129 // this SiteInstance becomes ref counted, by storing it in a scoped_refptr.
131 // The render process host factory may be nullptr. See SiteInstance
134 // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
136 static SiteInstance
* Create(content::BrowserContext
* browser_context
);
138 // Factory method to get the appropriate SiteInstance for the given URL, in
139 // a new BrowsingInstance. Use this instead of Create when you know the URL,
140 // since it allows special site grouping rules to be applied (for example,
141 // to group chrome-ui pages into the same instance).
142 static SiteInstance
* CreateForURL(
143 content::BrowserContext
* browser_context
, const GURL
& url
);
145 // Return whether both URLs are part of the same web site, for the purpose of
146 // assigning them to processes accordingly. The decision is currently based
147 // on the registered domain of the URLs (google.com, bbc.co.uk), as well as
148 // the scheme (https, http). This ensures that two pages will be in
149 // the same process if they can communicate with other via JavaScript.
150 // (e.g., docs.google.com and mail.google.com have DOM access to each other
151 // if they both set their document.domain properties to google.com.)
152 // Note that if the destination is a blank page, we consider that to be part
153 // of the same web site for the purposes for process assignment.
154 static bool IsSameWebSite(content::BrowserContext
* browser_context
,
156 const GURL
& dest_url
);
158 // Returns the site for the given URL, which includes only the scheme and
159 // registered domain. Returns an empty GURL if the URL has no host.
160 static GURL
GetSiteForURL(BrowserContext
* context
, const GURL
& url
);
163 friend class base::RefCounted
<SiteInstance
>;
166 virtual ~SiteInstance() {}
169 } // namespace content.
171 #endif // CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_