summaryrefslogtreecommitdiffstats
path: root/content/browser/browsing_instance.h
blob: 9347c90209c5350f132a0072e3916323c400e6dc (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
// Copyright (c) 2012 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 CONTENT_BROWSER_BROWSING_INSTANCE_H_
#define CONTENT_BROWSER_BROWSING_INSTANCE_H_
#pragma once

#include "base/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_context.h"

class GURL;
class SiteInstanceImpl;

namespace content {
class SiteInstance;
}

///////////////////////////////////////////////////////////////////////////////
//
// BrowsingInstance class
//
// A browsing instance corresponds to the notion of a "unit of related browsing
// contexts" in the HTML 5 spec.  Intuitively, it represents a collection of
// tabs and frames that can have script connections to each other.  In that
// sense, it reflects the user interface, and not the contents of the tabs and
// frames.
//
// We further subdivide a BrowsingInstance into SiteInstances, which represent
// the documents within each BrowsingInstance that are from the same site and
// thus can have script access to each other.  Different SiteInstances can
// safely run in different processes, because their documents cannot access
// each other's contents (due to the same origin policy).
//
// It is important to only have one SiteInstance per site within a given
// BrowsingInstance.  This is because any two documents from the same site
// might be able to script each other if they are in the same BrowsingInstance.
// Thus, they must be rendered in the same process.
//
// If the process-per-site model is in use, then we ensure that there is only
// one SiteInstance per site for the entire browser context, not just for each
// BrowsingInstance.  This reduces the number of renderer processes we create.
// (This is currently only true if --process-per-site is specified at the
// command line.)
//
// A BrowsingInstance is live as long as any SiteInstance has a reference to
// it.  A SiteInstance is live as long as any NavigationEntry or RenderViewHost
// have references to it.  Because both classes are RefCounted, they do not
// need to be manually deleted.
//
// BrowsingInstance has no public members, as it is designed to be
// visible only from the SiteInstance class.  To get a new
// SiteInstance that is part of the same BrowsingInstance, use
// SiteInstance::GetRelatedSiteInstance.  Because of this,
// BrowsingInstances and SiteInstances are tested together in
// site_instance_unittest.cc.
//
///////////////////////////////////////////////////////////////////////////////
class CONTENT_EXPORT BrowsingInstance
    : public base::RefCounted<BrowsingInstance> {
 protected:
  // Create a new BrowsingInstance.
  explicit BrowsingInstance(content::BrowserContext* context);

  // Returns whether the process-per-site model is in use (globally or just for
  // the given url), in which case we should ensure there is only one
  // SiteInstance per site for the entire browser context, not just for this
  // BrowsingInstance.
  virtual bool ShouldUseProcessPerSite(const GURL& url);

  // Get the browser context to which this BrowsingInstance belongs.
  content::BrowserContext* browser_context() const { return browser_context_; }

  // Returns whether this BrowsingInstance has registered a SiteInstance for
  // the site of the given URL.
  bool HasSiteInstance(const GURL& url);

  // Get the SiteInstance responsible for rendering the given URL.  Should
  // create a new one if necessary, but should not create more than one
  // SiteInstance per site.
  content::SiteInstance* GetSiteInstanceForURL(const GURL& url);

  // Adds the given SiteInstance to our map, to ensure that we do not create
  // another SiteInstance for the same site.
  void RegisterSiteInstance(content::SiteInstance* site_instance);

  // Removes the given SiteInstance from our map, after all references to it
  // have been deleted.  This means it is safe to create a new SiteInstance
  // if the user later visits a page from this site, within this
  // BrowsingInstance.
  void UnregisterSiteInstance(content::SiteInstance* site_instance);

  friend class SiteInstanceImpl;
  friend class content::SiteInstance;

  friend class base::RefCounted<BrowsingInstance>;

  // Virtual to allow tests to extend it.
  virtual ~BrowsingInstance();

 private:
  // Map of site to SiteInstance, to ensure we only have one SiteInstance per
  typedef base::hash_map<std::string, content::SiteInstance*> SiteInstanceMap;

  // Map of BrowserContext to SiteInstanceMap, for use in the process-per-site
  // model.
  typedef base::hash_map<content::BrowserContext*, SiteInstanceMap>
      ContextSiteInstanceMap;

  // Returns a pointer to the relevant SiteInstanceMap for this object.  If the
  // process-per-site model is in use, or if process-per-site-instance is in
  // use and |url| matches a site for which we always use one process (e.g.,
  // the new tab page), then this returns the SiteInstanceMap for the entire
  // browser context.  If not, this returns the BrowsingInstance's own private
  // SiteInstanceMap.
  SiteInstanceMap* GetSiteInstanceMap(content::BrowserContext* browser_context,
                                      const GURL& url);

  // Utility routine which removes the passed SiteInstance from the passed
  // SiteInstanceMap.
  bool RemoveSiteInstanceFromMap(SiteInstanceMap* map, const std::string& site,
                                 content::SiteInstance* site_instance);

  // Common browser context to which all SiteInstances in this BrowsingInstance
  // must belong.
  content::BrowserContext* const browser_context_;

  // Map of site to SiteInstance, to ensure we only have one SiteInstance per
  // site.  The site string should be the possibly_invalid_spec() of a GURL
  // obtained with SiteInstanceImpl::GetSiteForURL.  Note that this map may not
  // contain every active SiteInstance, because a race exists where two
  // SiteInstances can be assigned to the same site.  This is ok in rare cases.
  // This field is only used if we are not using process-per-site.
  SiteInstanceMap site_instance_map_;

  // Global map of BrowserContext to SiteInstanceMap, for process-per-site.
  static base::LazyInstance<ContextSiteInstanceMap>::Leaky
      context_site_instance_map_;

  DISALLOW_COPY_AND_ASSIGN(BrowsingInstance);
};

#endif  // CONTENT_BROWSER_BROWSING_INSTANCE_H_