| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/site_instance_impl.h" | 5 #include "content/browser/site_instance_impl.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "content/browser/browsing_instance.h" | 8 #include "content/browser/browsing_instance.h" |
| 9 #include "content/browser/child_process_security_policy_impl.h" | 9 #include "content/browser/child_process_security_policy_impl.h" |
| 10 #include "content/browser/frame_host/debug_urls.h" | 10 #include "content/browser/frame_host/debug_urls.h" |
| 11 #include "content/browser/frame_host/frame_tree_node.h" | 11 #include "content/browser/frame_host/frame_tree_node.h" |
| 12 #include "content/browser/renderer_host/render_process_host_impl.h" | 12 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 13 #include "content/browser/storage_partition_impl.h" | 13 #include "content/browser/storage_partition_impl.h" |
| 14 #include "content/common/site_isolation_policy.h" | 14 #include "content/common/site_isolation_policy.h" |
| 15 #include "content/public/browser/content_browser_client.h" | 15 #include "content/public/browser/content_browser_client.h" |
| 16 #include "content/public/browser/render_process_host_factory.h" | 16 #include "content/public/browser/render_process_host_factory.h" |
| 17 #include "content/public/browser/web_ui_controller_factory.h" | 17 #include "content/public/browser/web_ui_controller_factory.h" |
| 18 #include "content/public/common/url_constants.h" | 18 #include "content/public/common/url_constants.h" |
| 19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 20 | 20 |
| 21 namespace content { | 21 namespace content { |
| 22 | 22 |
| 23 const RenderProcessHostFactory* | |
| 24 SiteInstanceImpl::g_render_process_host_factory_ = NULL; | |
| 25 int32_t SiteInstanceImpl::next_site_instance_id_ = 1; | 23 int32_t SiteInstanceImpl::next_site_instance_id_ = 1; |
| 26 | 24 |
| 27 SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance) | 25 SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance) |
| 28 : id_(next_site_instance_id_++), | 26 : id_(next_site_instance_id_++), |
| 29 active_frame_count_(0), | 27 active_frame_count_(0), |
| 30 browsing_instance_(browsing_instance), | 28 browsing_instance_(browsing_instance), |
| 31 process_(nullptr), | 29 process_(nullptr), |
| 32 has_site_(false), | 30 has_site_(false), |
| 33 is_default_subframe_site_instance_(false) { | 31 process_reuse_policy_(ProcessReusePolicy::DEFAULT) { |
| 34 DCHECK(browsing_instance); | 32 DCHECK(browsing_instance); |
| 35 } | 33 } |
| 36 | 34 |
| 37 SiteInstanceImpl::~SiteInstanceImpl() { | 35 SiteInstanceImpl::~SiteInstanceImpl() { |
| 38 GetContentClient()->browser()->SiteInstanceDeleting(this); | 36 GetContentClient()->browser()->SiteInstanceDeleting(this); |
| 39 | 37 |
| 40 if (process_) | 38 if (process_) |
| 41 process_->RemoveObserver(this); | 39 process_->RemoveObserver(this); |
| 42 | 40 |
| 43 // Now that no one is referencing us, we can safely remove ourselves from | 41 // Now that no one is referencing us, we can safely remove ourselves from |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 browsing_instance_->browser_context(); | 74 browsing_instance_->browser_context(); |
| 77 if (has_site_ && | 75 if (has_site_ && |
| 78 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && | 76 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && |
| 79 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { | 77 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { |
| 80 return true; | 78 return true; |
| 81 } | 79 } |
| 82 | 80 |
| 83 return false; | 81 return false; |
| 84 } | 82 } |
| 85 | 83 |
| 86 namespace { | |
| 87 | |
| 88 const void* const kDefaultSubframeProcessHostHolderKey = | |
| 89 &kDefaultSubframeProcessHostHolderKey; | |
| 90 | |
| 91 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | |
| 92 public RenderProcessHostObserver { | |
| 93 public: | |
| 94 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) | |
| 95 : browser_context_(browser_context) {} | |
| 96 ~DefaultSubframeProcessHostHolder() override {} | |
| 97 | |
| 98 // Gets the correct render process to use for this SiteInstance. | |
| 99 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, | |
| 100 bool is_for_guests_only) { | |
| 101 StoragePartition* default_partition = | |
| 102 BrowserContext::GetDefaultStoragePartition(browser_context_); | |
| 103 StoragePartition* partition = | |
| 104 BrowserContext::GetStoragePartition(browser_context_, site_instance); | |
| 105 | |
| 106 // Is this the default storage partition? If it isn't, then just give it its | |
| 107 // own non-shared process. | |
| 108 if (partition != default_partition || is_for_guests_only) { | |
| 109 RenderProcessHostImpl* host = new RenderProcessHostImpl( | |
| 110 browser_context_, static_cast<StoragePartitionImpl*>(partition), | |
| 111 is_for_guests_only); | |
| 112 host->SetIsNeverSuitableForReuse(); | |
| 113 return host; | |
| 114 } | |
| 115 | |
| 116 if (host_) { | |
| 117 // If we already have a shared host for the default storage partition, use | |
| 118 // it. | |
| 119 return host_; | |
| 120 } | |
| 121 | |
| 122 host_ = new RenderProcessHostImpl( | |
| 123 browser_context_, static_cast<StoragePartitionImpl*>(partition), | |
| 124 false /* for guests only */); | |
| 125 host_->SetIsNeverSuitableForReuse(); | |
| 126 host_->AddObserver(this); | |
| 127 | |
| 128 return host_; | |
| 129 } | |
| 130 | |
| 131 void RenderProcessHostDestroyed(RenderProcessHost* host) override { | |
| 132 DCHECK_EQ(host_, host); | |
| 133 host_->RemoveObserver(this); | |
| 134 host_ = nullptr; | |
| 135 } | |
| 136 | |
| 137 private: | |
| 138 BrowserContext* browser_context_; | |
| 139 | |
| 140 // The default subframe render process used for the default storage partition | |
| 141 // of this BrowserContext. | |
| 142 RenderProcessHostImpl* host_ = nullptr; | |
| 143 }; | |
| 144 | |
| 145 } // namespace | |
| 146 | |
| 147 RenderProcessHost* SiteInstanceImpl::GetDefaultSubframeProcessHost( | |
| 148 BrowserContext* browser_context, | |
| 149 bool is_for_guests_only) { | |
| 150 DefaultSubframeProcessHostHolder* holder = | |
| 151 static_cast<DefaultSubframeProcessHostHolder*>( | |
| 152 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); | |
| 153 if (!holder) { | |
| 154 holder = new DefaultSubframeProcessHostHolder(browser_context); | |
| 155 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, | |
| 156 base::WrapUnique(holder)); | |
| 157 } | |
| 158 | |
| 159 return holder->GetProcessHost(this, is_for_guests_only); | |
| 160 } | |
| 161 | |
| 162 RenderProcessHost* SiteInstanceImpl::GetProcess() { | 84 RenderProcessHost* SiteInstanceImpl::GetProcess() { |
| 163 // TODO(erikkay) It would be nice to ensure that the renderer type had been | 85 // TODO(erikkay) It would be nice to ensure that the renderer type had been |
| 164 // properly set before we get here. The default tab creation case winds up | 86 // properly set before we get here. The default tab creation case winds up |
| 165 // with no site set at this point, so it will default to TYPE_NORMAL. This | 87 // with no site set at this point, so it will default to TYPE_NORMAL. This |
| 166 // may not be correct, so we'll wind up potentially creating a process that | 88 // may not be correct, so we'll wind up potentially creating a process that |
| 167 // we then throw away, or worse sharing a process with the wrong process type. | 89 // we then throw away, or worse sharing a process with the wrong process type. |
| 168 // See crbug.com/43448. | 90 // See crbug.com/43448. |
| 169 | 91 |
| 170 // Create a new process if ours went away or was reused. | 92 // Create a new process if ours went away or was reused. |
| 171 if (!process_) { | 93 if (!process_) { |
| 172 BrowserContext* browser_context = browsing_instance_->browser_context(); | 94 BrowserContext* browser_context = browsing_instance_->browser_context(); |
| 173 bool is_for_guests_only = site_.SchemeIs(kGuestScheme); | |
| 174 | 95 |
| 175 // If we should use process-per-site mode (either in general or for the | 96 // Check if the ProcessReusePolicy should be updated. |
| 176 // given site), then look for an existing RenderProcessHost for the site. | 97 bool should_use_process_per_site = |
| 177 bool use_process_per_site = has_site_ && | 98 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && |
| 178 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); | 99 has_site_; |
| 179 if (use_process_per_site) { | 100 if (should_use_process_per_site) { |
| 180 process_ = RenderProcessHostImpl::GetProcessHostForSite(browser_context, | 101 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE; |
| 181 site_); | 102 } else if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE) { |
| 103 process_reuse_policy_ = ProcessReusePolicy::DEFAULT; |
| 182 } | 104 } |
| 183 | 105 |
| 184 if (!process_ && IsDefaultSubframeSiteInstance() && | 106 process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance( |
| 185 SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) { | 107 browser_context, this); |
| 186 process_ = | |
| 187 GetDefaultSubframeProcessHost(browser_context, is_for_guests_only); | |
| 188 } | |
| 189 | 108 |
| 190 // If not (or if none found), see if we should reuse an existing process. | |
| 191 if (!process_ && RenderProcessHostImpl::ShouldTryToUseExistingProcessHost( | |
| 192 browser_context, site_)) { | |
| 193 process_ = RenderProcessHostImpl::GetExistingProcessHost(browser_context, | |
| 194 site_); | |
| 195 } | |
| 196 | |
| 197 // Otherwise (or if that fails), create a new one. | |
| 198 if (!process_) { | |
| 199 if (g_render_process_host_factory_) { | |
| 200 process_ = g_render_process_host_factory_->CreateRenderProcessHost( | |
| 201 browser_context, this); | |
| 202 } else { | |
| 203 StoragePartitionImpl* partition = | |
| 204 static_cast<StoragePartitionImpl*>( | |
| 205 BrowserContext::GetStoragePartition(browser_context, this)); | |
| 206 process_ = new RenderProcessHostImpl(browser_context, partition, | |
| 207 is_for_guests_only); | |
| 208 } | |
| 209 } | |
| 210 CHECK(process_); | 109 CHECK(process_); |
| 211 process_->AddObserver(this); | 110 process_->AddObserver(this); |
| 212 | 111 |
| 213 // If we are using process-per-site, we need to register this process | 112 // If we are using process-per-site, we need to register this process |
| 214 // for the current site so that we can find it again. (If no site is set | 113 // for the current site so that we can find it again. (If no site is set |
| 215 // at this time, we will register it in SetSite().) | 114 // at this time, we will register it in SetSite().) |
| 216 if (use_process_per_site) { | 115 if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE && |
| 116 has_site_) { |
| 217 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, | 117 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, |
| 218 process_, site_); | 118 process_, site_); |
| 219 } | 119 } |
| 220 | 120 |
| 221 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", | 121 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", |
| 222 "site id", id_, "process id", process_->GetID()); | 122 "site id", id_, "process id", process_->GetID()); |
| 223 GetContentClient()->browser()->SiteInstanceGotProcess(this); | 123 GetContentClient()->browser()->SiteInstanceGotProcess(this); |
| 224 | 124 |
| 225 if (has_site_) | 125 if (has_site_) |
| 226 LockToOrigin(); | 126 LockToOrigin(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 245 has_site_ = true; | 145 has_site_ = true; |
| 246 BrowserContext* browser_context = browsing_instance_->browser_context(); | 146 BrowserContext* browser_context = browsing_instance_->browser_context(); |
| 247 site_ = GetSiteForURL(browser_context, url); | 147 site_ = GetSiteForURL(browser_context, url); |
| 248 | 148 |
| 249 // Now that we have a site, register it with the BrowsingInstance. This | 149 // Now that we have a site, register it with the BrowsingInstance. This |
| 250 // ensures that we won't create another SiteInstance for this site within | 150 // ensures that we won't create another SiteInstance for this site within |
| 251 // the same BrowsingInstance, because all same-site pages within a | 151 // the same BrowsingInstance, because all same-site pages within a |
| 252 // BrowsingInstance can script each other. | 152 // BrowsingInstance can script each other. |
| 253 browsing_instance_->RegisterSiteInstance(this); | 153 browsing_instance_->RegisterSiteInstance(this); |
| 254 | 154 |
| 155 // Update the process reuse policy based on the site. |
| 156 bool should_use_process_per_site = |
| 157 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); |
| 158 if (should_use_process_per_site) { |
| 159 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE; |
| 160 } |
| 161 |
| 255 if (process_) { | 162 if (process_) { |
| 256 LockToOrigin(); | 163 LockToOrigin(); |
| 257 | 164 |
| 258 // Ensure the process is registered for this site if necessary. | 165 // Ensure the process is registered for this site if necessary. |
| 259 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_)) { | 166 if (should_use_process_per_site) { |
| 260 RenderProcessHostImpl::RegisterProcessHostForSite( | 167 RenderProcessHostImpl::RegisterProcessHostForSite( |
| 261 browser_context, process_, site_); | 168 browser_context, process_, site_); |
| 262 } | 169 } |
| 263 } | 170 } |
| 264 } | 171 } |
| 265 | 172 |
| 266 const GURL& SiteInstanceImpl::GetSiteURL() const { | 173 const GURL& SiteInstanceImpl::GetSiteURL() const { |
| 267 return site_; | 174 return site_; |
| 268 } | 175 } |
| 269 | 176 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 } | 223 } |
| 317 | 224 |
| 318 bool SiteInstanceImpl::RequiresDedicatedProcess() { | 225 bool SiteInstanceImpl::RequiresDedicatedProcess() { |
| 319 if (!has_site_) | 226 if (!has_site_) |
| 320 return false; | 227 return false; |
| 321 | 228 |
| 322 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); | 229 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); |
| 323 } | 230 } |
| 324 | 231 |
| 325 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { | 232 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { |
| 326 return is_default_subframe_site_instance_; | 233 return process_reuse_policy_ == |
| 234 ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS; |
| 327 } | 235 } |
| 328 | 236 |
| 329 void SiteInstanceImpl::IncrementActiveFrameCount() { | 237 void SiteInstanceImpl::IncrementActiveFrameCount() { |
| 330 active_frame_count_++; | 238 active_frame_count_++; |
| 331 } | 239 } |
| 332 | 240 |
| 333 void SiteInstanceImpl::DecrementActiveFrameCount() { | 241 void SiteInstanceImpl::DecrementActiveFrameCount() { |
| 334 if (--active_frame_count_ == 0) { | 242 if (--active_frame_count_ == 0) { |
| 335 for (auto& observer : observers_) | 243 for (auto& observer : observers_) |
| 336 observer.ActiveFrameCountIsZero(this); | 244 observer.ActiveFrameCountIsZero(this); |
| 337 } | 245 } |
| 338 } | 246 } |
| 339 | 247 |
| 340 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { | 248 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { |
| 341 browsing_instance_->increment_active_contents_count(); | 249 browsing_instance_->increment_active_contents_count(); |
| 342 } | 250 } |
| 343 | 251 |
| 344 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { | 252 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { |
| 345 browsing_instance_->decrement_active_contents_count(); | 253 browsing_instance_->decrement_active_contents_count(); |
| 346 } | 254 } |
| 347 | 255 |
| 348 void SiteInstanceImpl::AddObserver(Observer* observer) { | 256 void SiteInstanceImpl::AddObserver(Observer* observer) { |
| 349 observers_.AddObserver(observer); | 257 observers_.AddObserver(observer); |
| 350 } | 258 } |
| 351 | 259 |
| 352 void SiteInstanceImpl::RemoveObserver(Observer* observer) { | 260 void SiteInstanceImpl::RemoveObserver(Observer* observer) { |
| 353 observers_.RemoveObserver(observer); | 261 observers_.RemoveObserver(observer); |
| 354 } | 262 } |
| 355 | 263 |
| 356 void SiteInstanceImpl::set_render_process_host_factory( | |
| 357 const RenderProcessHostFactory* rph_factory) { | |
| 358 g_render_process_host_factory_ = rph_factory; | |
| 359 } | |
| 360 | |
| 361 BrowserContext* SiteInstanceImpl::GetBrowserContext() const { | 264 BrowserContext* SiteInstanceImpl::GetBrowserContext() const { |
| 362 return browsing_instance_->browser_context(); | 265 return browsing_instance_->browser_context(); |
| 363 } | 266 } |
| 364 | 267 |
| 365 // static | 268 // static |
| 366 scoped_refptr<SiteInstance> SiteInstance::Create( | 269 scoped_refptr<SiteInstance> SiteInstance::Create( |
| 367 BrowserContext* browser_context) { | 270 BrowserContext* browser_context) { |
| 368 return SiteInstanceImpl::Create(browser_context); | 271 return SiteInstanceImpl::Create(browser_context); |
| 369 } | 272 } |
| 370 | 273 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 browsing_instance_->browser_context(), site_)) | 426 browsing_instance_->browser_context(), site_)) |
| 524 return; | 427 return; |
| 525 | 428 |
| 526 ChildProcessSecurityPolicyImpl* policy = | 429 ChildProcessSecurityPolicyImpl* policy = |
| 527 ChildProcessSecurityPolicyImpl::GetInstance(); | 430 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 528 policy->LockToOrigin(process_->GetID(), site_); | 431 policy->LockToOrigin(process_->GetID(), site_); |
| 529 } | 432 } |
| 530 } | 433 } |
| 531 | 434 |
| 532 } // namespace content | 435 } // namespace content |
| OLD | NEW |