blob: 1e6b4b91485ae9a528beed77b12f6532e5968c07 [file] [log] [blame]
[email protected]72daaa92012-01-18 13:39:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]df8e899b2011-02-22 22:58:225#include "content/browser/browsing_instance.h"
initial.commit09911bf2008-07-26 23:55:296
7#include "base/command_line.h"
[email protected]dec76e802010-09-23 22:43:538#include "base/logging.h"
[email protected]b6583592012-01-25 19:52:339#include "content/browser/site_instance_impl.h"
[email protected]ccb797302011-12-15 16:55:1110#include "content/public/browser/browser_context.h"
Aaron Colwellddeccbdb2019-03-08 01:11:0311#include "content/public/browser/browser_or_resource_context.h"
[email protected]87f3c082011-10-19 18:07:4412#include "content/public/browser/content_browser_client.h"
Nick Carterbf6264a52018-04-06 02:39:3313#include "content/public/browser/site_isolation_policy.h"
Aaron Colwellddeccbdb2019-03-08 01:11:0314#include "content/public/common/content_features.h"
[email protected]c08950d22011-10-13 22:20:2915#include "content/public/common/content_switches.h"
[email protected]a1d29162011-10-14 17:14:0316#include "content/public/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2917
[email protected]46488322012-10-30 03:22:2018namespace content {
initial.commit09911bf2008-07-26 23:55:2919
Alex Moshchuk8e5c1952019-01-15 03:39:5020// Start the BrowsingInstance ID counter from 1 to avoid a conflict with the
21// invalid BrowsingInstanceId value, which is 0 in its underlying IdType32.
22int BrowsingInstance::next_browsing_instance_id_ = 1;
23
[email protected]46488322012-10-30 03:22:2024BrowsingInstance::BrowsingInstance(BrowserContext* browser_context)
Alex Moshchukf7488792019-03-11 22:37:5725 : isolation_context_(
Alex Moshchuk99b795422019-03-07 00:27:3226 BrowsingInstanceId::FromUnsafeValue(next_browsing_instance_id_++),
27 BrowserOrResourceContext(browser_context)),
Nate Chapin71da03c2019-02-05 01:21:4128 active_contents_count_(0u),
Aaron Colwellc1948312019-05-16 21:40:3029 default_process_(nullptr),
30 default_site_instance_(nullptr) {
Lukasz Anforowicz4726a172018-10-15 21:25:1031 DCHECK(browser_context);
[email protected]dec76e802010-09-23 22:43:5332}
33
Nate Chapin71da03c2019-02-05 01:21:4134void BrowsingInstance::RenderProcessHostDestroyed(RenderProcessHost* host) {
35 DCHECK_EQ(default_process_, host);
36 // Only clear the default process if the RenderProcessHost object goes away,
37 // not if the renderer process goes away while the RenderProcessHost remains.
38 default_process_->RemoveObserver(this);
39 default_process_ = nullptr;
40}
41
Alex Moshchukf7488792019-03-11 22:37:5742BrowserContext* BrowsingInstance::GetBrowserContext() const {
43 return isolation_context_.browser_or_resource_context().ToBrowserContext();
44}
45
Nate Chapin71da03c2019-02-05 01:21:4146void BrowsingInstance::SetDefaultProcess(RenderProcessHost* default_process) {
47 DCHECK(!default_process_);
Aaron Colwellddeccbdb2019-03-08 01:11:0348 DCHECK(!default_site_instance_);
Nate Chapin71da03c2019-02-05 01:21:4149 default_process_ = default_process;
50 default_process_->AddObserver(this);
51}
52
Aaron Colwellddeccbdb2019-03-08 01:11:0353bool BrowsingInstance::IsDefaultSiteInstance(
54 const SiteInstanceImpl* site_instance) const {
Aaron Colwellc1948312019-05-16 21:40:3055 return site_instance != nullptr && site_instance == default_site_instance_;
Aaron Colwellddeccbdb2019-03-08 01:11:0356}
57
Aaron Colwell0447cd02019-06-26 22:04:2058bool BrowsingInstance::IsSiteInDefaultSiteInstance(const GURL& site_url) const {
59 return site_url_set_.find(site_url) != site_url_set_.end();
60}
61
initial.commit09911bf2008-07-26 23:55:2962bool BrowsingInstance::HasSiteInstance(const GURL& url) {
Aaron Colwell24f2746a2019-04-25 16:57:4363 std::string site = GetSiteForURL(url).possibly_invalid_spec();
[email protected]41fb79a52012-06-29 16:34:3364 return site_instance_map_.find(site) != site_instance_map_.end();
initial.commit09911bf2008-07-26 23:55:2965}
66
dchengbccd6b82016-03-30 16:24:1967scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
Aaron Colwellddeccbdb2019-03-08 01:11:0368 const GURL& url,
69 bool allow_default_instance) {
70 scoped_refptr<SiteInstanceImpl> site_instance =
71 GetSiteInstanceForURLHelper(url, allow_default_instance);
initial.commit09911bf2008-07-26 23:55:2972
Aaron Colwellddeccbdb2019-03-08 01:11:0373 if (site_instance)
74 return site_instance;
[email protected]41fb79a52012-06-29 16:34:3375
initial.commit09911bf2008-07-26 23:55:2976 // No current SiteInstance for this site, so let's create one.
dchengbccd6b82016-03-30 16:24:1977 scoped_refptr<SiteInstanceImpl> instance = new SiteInstanceImpl(this);
initial.commit09911bf2008-07-26 23:55:2978
Charlie Reisc2099752019-04-06 01:21:1279 // Set the site of this new SiteInstance, which will register it with us,
80 // unless this URL should leave the SiteInstance's site unassigned.
81 if (SiteInstance::ShouldAssignSiteForURL(url))
82 instance->SetSite(url);
initial.commit09911bf2008-07-26 23:55:2983 return instance;
84}
85
Aaron Colwellddeccbdb2019-03-08 01:11:0386void BrowsingInstance::GetSiteAndLockForURL(const GURL& url,
87 bool allow_default_instance,
88 GURL* site_url,
89 GURL* lock_url) {
90 scoped_refptr<SiteInstanceImpl> site_instance =
91 GetSiteInstanceForURLHelper(url, allow_default_instance);
92
93 if (site_instance) {
94 *site_url = site_instance->GetSiteURL();
95 *lock_url = site_instance->lock_url();
96 return;
97 }
98
Aaron Colwell24f2746a2019-04-25 16:57:4399 *site_url = GetSiteForURL(url);
Alex Moshchukf7488792019-03-11 22:37:57100 *lock_url =
101 SiteInstanceImpl::DetermineProcessLockURL(isolation_context_, url);
Aaron Colwellddeccbdb2019-03-08 01:11:03102}
103
Aaron Colwelle953e562019-07-24 16:47:36104bool BrowsingInstance::TrySettingDefaultSiteInstance(
105 SiteInstanceImpl* site_instance,
106 const GURL& url) {
107 DCHECK(!site_instance->HasSite());
108 const GURL site_url = GetSiteForURL(url);
109 if (default_site_instance_ ||
110 !SiteInstanceImpl::CanBePlacedInDefaultSiteInstance(isolation_context_,
111 url, site_url)) {
112 return false;
113 }
114
115 // Note: |default_site_instance_| must be set before SetSite() call to
116 // properly trigger default SiteInstance behavior inside that method.
117 default_site_instance_ = site_instance;
118 site_instance->SetSite(SiteInstanceImpl::GetDefaultSiteURL());
119 site_url_set_.insert(site_url);
120 return true;
121}
122
Aaron Colwellddeccbdb2019-03-08 01:11:03123scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURLHelper(
124 const GURL& url,
125 bool allow_default_instance) {
Aaron Colwell0447cd02019-06-26 22:04:20126 const GURL site_url = GetSiteForURL(url);
127 auto i = site_instance_map_.find(site_url.possibly_invalid_spec());
Aaron Colwellddeccbdb2019-03-08 01:11:03128 if (i != site_instance_map_.end())
129 return i->second;
130
131 // Check to see if we can use the default SiteInstance for sites that don't
Aaron Colwell8bb0ada2019-07-18 22:41:23132 // need to be isolated in their own process.
133 if (allow_default_instance &&
134 SiteInstanceImpl::CanBePlacedInDefaultSiteInstance(isolation_context_,
135 url, site_url)) {
Aaron Colwellddeccbdb2019-03-08 01:11:03136 DCHECK(!default_process_);
Aaron Colwellc1948312019-05-16 21:40:30137 scoped_refptr<SiteInstanceImpl> site_instance = default_site_instance_;
138 if (!site_instance) {
139 site_instance = new SiteInstanceImpl(this);
140
141 // Keep a copy of the pointer so it can be used for other URLs. This is
142 // safe because the SiteInstanceImpl destructor will call
143 // UnregisterSiteInstance() to clear this copy when the last
144 // reference to |site_instance| is destroyed.
145 // Note: This assignment MUST happen before the SetSite() call to ensure
146 // this instance is not added to |site_instance_map_| when SetSite()
147 // calls RegisterSiteInstance().
148 default_site_instance_ = site_instance.get();
149
150 site_instance->SetSite(SiteInstanceImpl::GetDefaultSiteURL());
Aaron Colwellddeccbdb2019-03-08 01:11:03151 }
Aaron Colwell0447cd02019-06-26 22:04:20152
153 // Add |site_url| to the set so we can keep track of all the sites the
154 // the default SiteInstance has been returned for.
155 site_url_set_.insert(site_url);
Aaron Colwellc1948312019-05-16 21:40:30156 return site_instance;
Aaron Colwellddeccbdb2019-03-08 01:11:03157 }
158
159 return nullptr;
160}
161
dchengbccd6b82016-03-30 16:24:19162void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
163 DCHECK(site_instance->browsing_instance_.get() == this);
164 DCHECK(site_instance->HasSite());
nickd5bbd0b2016-03-31 19:52:44165
Aaron Colwellddeccbdb2019-03-08 01:11:03166 // Explicitly prevent the |default_site_instance_| from being added since
167 // the map is only supposed to contain instances that map to a single site.
Aaron Colwellc1948312019-05-16 21:40:30168 if (site_instance == default_site_instance_)
Aaron Colwellddeccbdb2019-03-08 01:11:03169 return;
170
[email protected]77ab17312012-09-28 15:34:59171 std::string site = site_instance->GetSiteURL().possibly_invalid_spec();
initial.commit09911bf2008-07-26 23:55:29172
173 // Only register if we don't have a SiteInstance for this site already.
174 // It's possible to have two SiteInstances point to the same site if two
175 // tabs are navigated there at the same time. (We don't call SetSite or
176 // register them until DidNavigate.) If there is a previously existing
177 // SiteInstance for this site, we just won't register the new one.
jdoerrie55ec69d2018-10-08 13:34:46178 auto i = site_instance_map_.find(site);
[email protected]41fb79a52012-06-29 16:34:33179 if (i == site_instance_map_.end()) {
initial.commit09911bf2008-07-26 23:55:29180 // Not previously registered, so register it.
[email protected]41fb79a52012-06-29 16:34:33181 site_instance_map_[site] = site_instance;
initial.commit09911bf2008-07-26 23:55:29182 }
183}
184
dchengbccd6b82016-03-30 16:24:19185void BrowsingInstance::UnregisterSiteInstance(SiteInstanceImpl* site_instance) {
186 DCHECK(site_instance->browsing_instance_.get() == this);
187 DCHECK(site_instance->HasSite());
Aaron Colwellc1948312019-05-16 21:40:30188
189 if (site_instance == default_site_instance_) {
190 // The last reference to the default SiteInstance is being destroyed.
191 default_site_instance_ = nullptr;
192 }
193
[email protected]77ab17312012-09-28 15:34:59194 std::string site = site_instance->GetSiteURL().possibly_invalid_spec();
initial.commit09911bf2008-07-26 23:55:29195
196 // Only unregister the SiteInstance if it is the same one that is registered
197 // for the site. (It might have been an unregistered SiteInstance. See the
198 // comments in RegisterSiteInstance.)
jdoerrie55ec69d2018-10-08 13:34:46199 auto i = site_instance_map_.find(site);
[email protected]41fb79a52012-06-29 16:34:33200 if (i != site_instance_map_.end() && i->second == site_instance) {
initial.commit09911bf2008-07-26 23:55:29201 // Matches, so erase it.
[email protected]41fb79a52012-06-29 16:34:33202 site_instance_map_.erase(i);
initial.commit09911bf2008-07-26 23:55:29203 }
204}
[email protected]dec76e802010-09-23 22:43:53205
Alex Moshchuk8e5c1952019-01-15 03:39:50206// static
207BrowsingInstanceId BrowsingInstance::NextBrowsingInstanceId() {
208 return BrowsingInstanceId::FromUnsafeValue(next_browsing_instance_id_);
209}
210
[email protected]dec76e802010-09-23 22:43:53211BrowsingInstance::~BrowsingInstance() {
212 // We should only be deleted when all of the SiteInstances that refer to
213 // us are gone.
214 DCHECK(site_instance_map_.empty());
[email protected]d5072a82014-05-15 05:50:18215 DCHECK_EQ(0u, active_contents_count_);
Aaron Colwellc1948312019-05-16 21:40:30216 DCHECK(!default_site_instance_);
Nate Chapin71da03c2019-02-05 01:21:41217 if (default_process_)
218 default_process_->RemoveObserver(this);
[email protected]dec76e802010-09-23 22:43:53219}
[email protected]46488322012-10-30 03:22:20220
Aaron Colwellf35ff832019-04-25 18:05:43221GURL BrowsingInstance::GetSiteForURL(const GURL& url) const {
Aaron Colwell24f2746a2019-04-25 16:57:43222 return SiteInstanceImpl::GetSiteForURL(isolation_context_, url);
223}
224
[email protected]46488322012-10-30 03:22:20225} // namespace content