site_instance.h revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
6#define CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
7
8#include "base/basictypes.h"
9#include "base/memory/ref_counted.h"
10#include "content/common/content_export.h"
11#include "url/gurl.h"
12
13namespace content {
14class BrowserContext;
15class BrowsingInstance;
16class RenderProcessHost;
17
18///////////////////////////////////////////////////////////////////////////////
19// SiteInstance interface.
20//
21// A SiteInstance represents a group of web pages that may be able to
22// synchronously script each other, and thus must live in the same renderer
23// process.
24//
25// We identify this group using a combination of where the page comes from
26// (the site) and which tabs have references to each other (the instance).
27// Here, a "site" is similar to the page's origin, but it only includes the
28// registered domain name and scheme, not the port or subdomains.  This accounts
29// for the fact that changes to document.domain allow similar origin pages with
30// different ports or subdomains to script each other.  An "instance" includes
31// all tabs that might be able to script each other because of how they were
32// created (e.g., window.open or targeted links).  We represent instances using
33// the BrowsingInstance class.
34//
35// Process models:
36//
37// In process-per-site-instance (the current default process model),
38// SiteInstances are created (1) when the user manually creates a new tab
39// (which also creates a new BrowsingInstance), and (2) when the user navigates
40// across site boundaries (which uses the same BrowsingInstance).  If the user
41// navigates within a site, the same SiteInstance is used.
42// (Caveat: we currently allow renderer-initiated cross-site navigations to
43// stay in the same SiteInstance, to preserve compatibility in cases like
44// cross-site iframes that open popups.)
45//
46// In --process-per-tab, SiteInstances are created when the user manually
47// creates a new tab, but not when navigating across site boundaries (unless
48// a process swap is required for security reasons, such as navigating from
49// a privileged WebUI page to a normal web page).  This corresponds to one
50// process per BrowsingInstance.
51//
52// In --process-per-site, we consolidate all SiteInstances for a given site into
53// the same process, throughout the entire browser context.  This ensures that
54// only one process will be used for each site.
55//
56// Each NavigationEntry for a WebContents points to the SiteInstance that
57// rendered it.  Each RenderViewHost also points to the SiteInstance that it is
58// associated with.  A SiteInstance keeps track of the number of these
59// references and deletes itself when the count goes to zero.  This means that
60// a SiteInstance is only live as long as it is accessible, either from new
61// tabs with no NavigationEntries or in NavigationEntries in the history.
62//
63///////////////////////////////////////////////////////////////////////////////
64class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
65 public:
66  // Returns a unique ID for this SiteInstance.
67  virtual int32 GetId() = 0;
68
69  // Whether this SiteInstance has a running process associated with it.
70  // This may return true before the first call to GetProcess(), in cases where
71  // we use process-per-site and there is an existing process available.
72  virtual bool HasProcess() const = 0;
73
74  // Returns the current process being used to render pages in this
75  // SiteInstance.  If the process has not yet been created or has cleanly
76  // exited (e.g., when it is not actively being used), then this method will
77  // create a new process with a new ID.  Note that renderer process crashes
78  // leave the current RenderProcessHost (and ID) in place.
79  //
80  // For sites that require process-per-site mode (e.g., WebUI), this will
81  // ensure only one RenderProcessHost for the site exists/ within the
82  // BrowserContext.
83  virtual content::RenderProcessHost* GetProcess() = 0;
84
85  // Browser context to which this SiteInstance (and all related
86  // SiteInstances) belongs.
87  virtual content::BrowserContext* GetBrowserContext() const = 0;
88
89  // Get the web site that this SiteInstance is rendering pages for.
90  // This includes the scheme and registered domain, but not the port.
91  virtual const GURL& GetSiteURL() const = 0;
92
93  // Gets a SiteInstance for the given URL that shares the current
94  // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
95  // that a BrowsingInstance only has one SiteInstance per site, so that pages
96  // in a BrowsingInstance have the ability to script each other.  Callers
97  // should ensure that this SiteInstance becomes ref counted, by storing it in
98  // a scoped_refptr.  (By having this method, we can hide the BrowsingInstance
99  // class from the rest of the codebase.)
100  // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
101  // Darin suggests.
102  virtual SiteInstance* GetRelatedSiteInstance(const GURL& url) = 0;
103
104  // Returns whether the given SiteInstance is in the same BrowsingInstance as
105  // this one.  If so, JavaScript interactions that are permitted across
106  // origins (e.g., postMessage) should be supported.
107  virtual bool IsRelatedSiteInstance(const SiteInstance* instance) = 0;
108
109  // Factory method to create a new SiteInstance.  This will create a new
110  // new BrowsingInstance, so it should only be used when creating a new tab
111  // from scratch (or similar circumstances).  Callers should ensure that
112  // this SiteInstance becomes ref counted, by storing it in a scoped_refptr.
113  //
114  // The render process host factory may be NULL. See SiteInstance constructor.
115  //
116  // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
117  // Darin suggests.
118  static SiteInstance* Create(content::BrowserContext* browser_context);
119
120  // Factory method to get the appropriate SiteInstance for the given URL, in
121  // a new BrowsingInstance.  Use this instead of Create when you know the URL,
122  // since it allows special site grouping rules to be applied (for example,
123  // to group chrome-ui pages into the same instance).
124  static SiteInstance* CreateForURL(
125      content::BrowserContext* browser_context, const GURL& url);
126
127  // Return whether both URLs are part of the same web site, for the purpose of
128  // assigning them to processes accordingly.  The decision is currently based
129  // on the registered domain of the URLs (google.com, bbc.co.uk), as well as
130  // the scheme (https, http).  This ensures that two pages will be in
131  // the same process if they can communicate with other via JavaScript.
132  // (e.g., docs.google.com and mail.google.com have DOM access to each other
133  // if they both set their document.domain properties to google.com.)
134  static bool IsSameWebSite(content::BrowserContext* browser_context,
135                            const GURL& url1, const GURL& url2);
136
137  // Returns the site for the given URL, which includes only the scheme and
138  // registered domain.  Returns an empty GURL if the URL has no host.
139  static GURL GetSiteForURL(BrowserContext* context, const GURL& url);
140
141 protected:
142  friend class base::RefCounted<SiteInstance>;
143
144  SiteInstance() {}
145  virtual ~SiteInstance() {}
146};
147
148}  // namespace content.
149
150#endif  // CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
151