summaryrefslogtreecommitdiffstats
path: root/chrome/browser/site_instance.h
blob: 6759fe3c223fb05ad33780b8867766afc1e15529 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SITE_INSTANCE_H__
#define CHROME_BROWSER_SITE_INSTANCE_H__

#include "chrome/browser/browsing_instance.h"
#include "chrome/browser/render_process_host.h"
#include "googleurl/src/gurl.h"

///////////////////////////////////////////////////////////////////////////////
//
// SiteInstance class
//
// A SiteInstance is a data structure that is associated with all pages in a
// given instance of a web site.  Here, a web site is identified by its
// registered domain name and scheme.  An instance includes all pages
// that are connected (i.e., either a user or a script navigated from one
// to the other).  We represent instances using the BrowsingInstance class.
//
// In --process-per-tab, one SiteInstance is created for each tab (i.e., in the
// WebContents constructor), unless the tab is created by script (i.e., in
// WebContents::CreateNewView).  This corresponds to one process per
// BrowsingInstance.
//
// In process-per-site-instance (the current default process model),
// SiteInstances are created (1) when the user manually creates a new tab
// (which also creates a new BrowsingInstance), and (2) when the user navigates
// across site boundaries (which uses the same BrowsingInstance).  If the user
// navigates within a site, or opens links in new tabs within a site, the same
// SiteInstance is used.
//
// In --process-per-site, we consolidate all SiteInstances for a given site,
// throughout the entire profile.  This ensures that only one process will be
// dedicated to each site.
//
// Each NavigationEntry for a WebContents points to the SiteInstance that
// rendered it.  Each RenderViewHost also points to the SiteInstance that it is
// associated with.  A SiteInstance keeps track of the number of these
// references and deletes itself when the count goes to zero.  This means that
// a SiteInstance is only live as long as it is accessible, either from new
// tabs with no NavigationEntries or in NavigationEntries in the history.
//
///////////////////////////////////////////////////////////////////////////////
class SiteInstance : public base::RefCounted<SiteInstance> {
 public:
  // Virtual to allow tests to extend it.
  virtual ~SiteInstance();

  // Get the BrowsingInstance to which this SiteInstance belongs.
  BrowsingInstance* browsing_instance() { return browsing_instance_; }

  // Set / Get the host ID for this SiteInstance's current RenderProcessHost.
  void set_process_host_id(int process_host_id) {
    process_host_id_ = process_host_id;
  }
  int process_host_id() const { return process_host_id_; }

  // Update / Get the max page ID for this SiteInstance.
  void UpdateMaxPageID(int32 page_id) {
    if (page_id > max_page_id_)
      max_page_id_ = page_id;
  }
  int32 max_page_id() const { return max_page_id_; }

  // Returns the current process being used to render pages in this
  // SiteInstance.  If the process has crashed or otherwise gone away, then
  // this method will create a new process and update our host ID accordingly.
  RenderProcessHost* GetProcess();

  // Set / Get the web site that this SiteInstance is rendering pages for.
  // This includes the scheme and registered domain, but not the port.  If the
  // URL does not have a valid registered domain, then the full hostname is
  // stored.
  void SetSite(const GURL& url);
  const GURL& site() const { return site_; }
  bool has_site() const { return has_site_; }

  // Returns whether there is currently a related SiteInstance (registered with
  // BrowsingInstance) for the site of the given url.  If so, we should try to
  // avoid dedicating an unused SiteInstance to it (e.g., in a new tab).
  bool HasRelatedSiteInstance(const GURL& url);

  // Gets a SiteInstance for the given URL that shares the current
  // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
  // that a BrowsingInstance only has one SiteInstance per site, so that pages
  // in a BrowsingInstance have the ability to script each other.  Callers
  // should ensure that this SiteInstance becomes ref counted, by storing it in
  // a scoped_refptr.  (By having this method, we can hide the BrowsingInstance
  // class from the rest of the codebase.)
  // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
  // Darin suggests.
  SiteInstance* GetRelatedSiteInstance(const GURL& url);

  // Factory method to create a new SiteInstance.  This will create a new
  // new BrowsingInstance, so it should only be used when creating a new tab
  // from scratch (or similar circumstances).  Callers should ensure that
  // this SiteInstance becomes ref counted, by storing it in a scoped_refptr.
  // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
  // Darin suggests.
  static SiteInstance* CreateSiteInstance(Profile* profile);

  // Returns the site for the given URL, which includes only the scheme and
  // registered domain.  Returns an empty GURL if the URL has no host.
  static GURL GetSiteForURL(const GURL& url);

  // Return whether both URLs are part of the same web site, for the purpose of
  // assigning them to processes accordingly.  The decision is currently based
  // on the registered domain of the URLs (google.com, bbc.co.uk), as well as
  // the scheme (https, http).  This ensures that two pages will be in
  // the same process if they can communicate with other via JavaScript.
  // (e.g., docs.google.com and mail.google.com have DOM access to each other
  // if they both set their document.domain properties to google.com.)
  static bool IsSameWebSite(const GURL& url1, const GURL& url2);

 protected:
  friend class BrowsingInstance;

  // Create a new SiteInstance.  Protected to give access to BrowsingInstance
  // and tests; most callers should use CreateSiteInstance or
  // GetRelatedSiteInstance instead.
  SiteInstance(BrowsingInstance* browsing_instance)
      : browsing_instance_(browsing_instance),
        process_host_id_(-1),
        max_page_id_(-1),
        has_site_(false) {
    DCHECK(browsing_instance);
  }

 private:
  // BrowsingInstance to which this SiteInstance belongs.
  scoped_refptr<BrowsingInstance> browsing_instance_;

  // Current host ID for the RenderProcessHost that is rendering pages for this
  // SiteInstance.  If the rendering process dies, this host ID can be
  // replaced when a new process is created, without losing the association
  // between all pages in this SiteInstance.
  int process_host_id_;

  // The current max_page_id in the SiteInstance's RenderProcessHost.  If the
  // rendering process dies, its replacement should start issuing page IDs that
  // are larger than this value.
  int32 max_page_id_;

  // The web site that this SiteInstance is rendering pages for.
  GURL site_;

  // Whether SetSite has been called.
  bool has_site_;

  DISALLOW_EVIL_CONSTRUCTORS(SiteInstance);
};

#endif  //  CHROME_BROWSER_SITE_INSTANCE_H__