Chromium Code Reviews| 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_( |
| 32 RenderProcessHostImpl::ProcessReusePolicy::DEFAULT) { | |
| 34 DCHECK(browsing_instance); | 33 DCHECK(browsing_instance); |
| 35 } | 34 } |
| 36 | 35 |
| 37 SiteInstanceImpl::~SiteInstanceImpl() { | 36 SiteInstanceImpl::~SiteInstanceImpl() { |
| 38 GetContentClient()->browser()->SiteInstanceDeleting(this); | 37 GetContentClient()->browser()->SiteInstanceDeleting(this); |
| 39 | 38 |
| 40 if (process_) | 39 if (process_) |
| 41 process_->RemoveObserver(this); | 40 process_->RemoveObserver(this); |
| 42 | 41 |
| 43 // Now that no one is referencing us, we can safely remove ourselves from | 42 // 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(); | 75 browsing_instance_->browser_context(); |
| 77 if (has_site_ && | 76 if (has_site_ && |
| 78 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && | 77 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && |
| 79 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { | 78 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { |
| 80 return true; | 79 return true; |
| 81 } | 80 } |
| 82 | 81 |
| 83 return false; | 82 return false; |
| 84 } | 83 } |
| 85 | 84 |
| 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) { | |
|
nasko
2017/05/03 23:46:17
Ok, I didn't realize this is code that just moved
clamy
2017/05/04 15:56:19
I did the modifications as requested in the other
| |
| 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() { | 85 RenderProcessHost* SiteInstanceImpl::GetProcess() { |
| 163 // TODO(erikkay) It would be nice to ensure that the renderer type had been | 86 // 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 | 87 // 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 | 88 // 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 | 89 // 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. | 90 // we then throw away, or worse sharing a process with the wrong process type. |
| 168 // See crbug.com/43448. | 91 // See crbug.com/43448. |
| 169 | 92 |
| 170 // Create a new process if ours went away or was reused. | 93 // Create a new process if ours went away or was reused. |
| 171 if (!process_) { | 94 if (!process_) { |
| 172 BrowserContext* browser_context = browsing_instance_->browser_context(); | 95 BrowserContext* browser_context = browsing_instance_->browser_context(); |
| 173 bool is_for_guests_only = site_.SchemeIs(kGuestScheme); | 96 process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance( |
| 97 browser_context, this); | |
| 174 | 98 |
| 175 // If we should use process-per-site mode (either in general or for the | |
| 176 // given site), then look for an existing RenderProcessHost for the site. | |
| 177 bool use_process_per_site = has_site_ && | |
| 178 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); | |
| 179 if (use_process_per_site) { | |
| 180 process_ = RenderProcessHostImpl::GetProcessHostForSite(browser_context, | |
| 181 site_); | |
| 182 } | |
| 183 | |
| 184 if (!process_ && IsDefaultSubframeSiteInstance() && | |
| 185 SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) { | |
| 186 process_ = | |
| 187 GetDefaultSubframeProcessHost(browser_context, is_for_guests_only); | |
| 188 } | |
| 189 | |
| 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_); | 99 CHECK(process_); |
| 211 process_->AddObserver(this); | 100 process_->AddObserver(this); |
| 212 | 101 |
| 213 // If we are using process-per-site, we need to register this process | 102 // 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 | 103 // 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().) | 104 // at this time, we will register it in SetSite().) |
| 216 if (use_process_per_site) { | 105 if (process_reuse_policy_ == |
| 106 RenderProcessHostImpl::ProcessReusePolicy::PROCESS_PER_SITE && | |
| 107 has_site_) { | |
| 217 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, | 108 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, |
|
Charlie Reis
2017/05/03 23:28:00
Ah, I suppose there's still a fair amount needed b
clamy
2017/05/04 15:56:19
Indeed. The goal of this patch is to move the code
| |
| 218 process_, site_); | 109 process_, site_); |
| 219 } | 110 } |
| 220 | 111 |
| 221 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", | 112 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", |
| 222 "site id", id_, "process id", process_->GetID()); | 113 "site id", id_, "process id", process_->GetID()); |
| 223 GetContentClient()->browser()->SiteInstanceGotProcess(this); | 114 GetContentClient()->browser()->SiteInstanceGotProcess(this); |
| 224 | 115 |
| 225 if (has_site_) | 116 if (has_site_) |
| 226 LockToOrigin(); | 117 LockToOrigin(); |
| 227 } | 118 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 245 has_site_ = true; | 136 has_site_ = true; |
| 246 BrowserContext* browser_context = browsing_instance_->browser_context(); | 137 BrowserContext* browser_context = browsing_instance_->browser_context(); |
| 247 site_ = GetSiteForURL(browser_context, url); | 138 site_ = GetSiteForURL(browser_context, url); |
| 248 | 139 |
| 249 // Now that we have a site, register it with the BrowsingInstance. This | 140 // 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 | 141 // ensures that we won't create another SiteInstance for this site within |
| 251 // the same BrowsingInstance, because all same-site pages within a | 142 // the same BrowsingInstance, because all same-site pages within a |
| 252 // BrowsingInstance can script each other. | 143 // BrowsingInstance can script each other. |
| 253 browsing_instance_->RegisterSiteInstance(this); | 144 browsing_instance_->RegisterSiteInstance(this); |
| 254 | 145 |
| 146 // Update the process reuse policy based on the site. | |
| 147 bool should_use_process_per_site = | |
| 148 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); | |
| 149 if (should_use_process_per_site) { | |
| 150 process_reuse_policy_ = | |
| 151 RenderProcessHostImpl::ProcessReusePolicy::PROCESS_PER_SITE; | |
| 152 } | |
| 153 | |
| 255 if (process_) { | 154 if (process_) { |
| 256 LockToOrigin(); | 155 LockToOrigin(); |
| 257 | 156 |
| 258 // Ensure the process is registered for this site if necessary. | 157 // Ensure the process is registered for this site if necessary. |
| 259 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_)) { | 158 if (should_use_process_per_site) { |
| 260 RenderProcessHostImpl::RegisterProcessHostForSite( | 159 RenderProcessHostImpl::RegisterProcessHostForSite( |
| 261 browser_context, process_, site_); | 160 browser_context, process_, site_); |
| 262 } | 161 } |
| 263 } | 162 } |
| 264 } | 163 } |
| 265 | 164 |
| 266 const GURL& SiteInstanceImpl::GetSiteURL() const { | 165 const GURL& SiteInstanceImpl::GetSiteURL() const { |
| 267 return site_; | 166 return site_; |
| 268 } | 167 } |
| 269 | 168 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 } | 215 } |
| 317 | 216 |
| 318 bool SiteInstanceImpl::RequiresDedicatedProcess() { | 217 bool SiteInstanceImpl::RequiresDedicatedProcess() { |
| 319 if (!has_site_) | 218 if (!has_site_) |
| 320 return false; | 219 return false; |
| 321 | 220 |
| 322 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); | 221 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); |
| 323 } | 222 } |
| 324 | 223 |
| 325 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { | 224 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { |
| 326 return is_default_subframe_site_instance_; | 225 return process_reuse_policy_ == RenderProcessHostImpl::ProcessReusePolicy:: |
| 226 USE_DEFAULT_SUBFRAME_INSTANCE; | |
| 327 } | 227 } |
| 328 | 228 |
| 329 void SiteInstanceImpl::IncrementActiveFrameCount() { | 229 void SiteInstanceImpl::IncrementActiveFrameCount() { |
| 330 active_frame_count_++; | 230 active_frame_count_++; |
| 331 } | 231 } |
| 332 | 232 |
| 333 void SiteInstanceImpl::DecrementActiveFrameCount() { | 233 void SiteInstanceImpl::DecrementActiveFrameCount() { |
| 334 if (--active_frame_count_ == 0) { | 234 if (--active_frame_count_ == 0) { |
| 335 for (auto& observer : observers_) | 235 for (auto& observer : observers_) |
| 336 observer.ActiveFrameCountIsZero(this); | 236 observer.ActiveFrameCountIsZero(this); |
| 337 } | 237 } |
| 338 } | 238 } |
| 339 | 239 |
| 340 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { | 240 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { |
| 341 browsing_instance_->increment_active_contents_count(); | 241 browsing_instance_->increment_active_contents_count(); |
| 342 } | 242 } |
| 343 | 243 |
| 344 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { | 244 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { |
| 345 browsing_instance_->decrement_active_contents_count(); | 245 browsing_instance_->decrement_active_contents_count(); |
| 346 } | 246 } |
| 347 | 247 |
| 348 void SiteInstanceImpl::AddObserver(Observer* observer) { | 248 void SiteInstanceImpl::AddObserver(Observer* observer) { |
| 349 observers_.AddObserver(observer); | 249 observers_.AddObserver(observer); |
| 350 } | 250 } |
| 351 | 251 |
| 352 void SiteInstanceImpl::RemoveObserver(Observer* observer) { | 252 void SiteInstanceImpl::RemoveObserver(Observer* observer) { |
| 353 observers_.RemoveObserver(observer); | 253 observers_.RemoveObserver(observer); |
| 354 } | 254 } |
| 355 | 255 |
| 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 { | 256 BrowserContext* SiteInstanceImpl::GetBrowserContext() const { |
| 362 return browsing_instance_->browser_context(); | 257 return browsing_instance_->browser_context(); |
| 363 } | 258 } |
| 364 | 259 |
| 365 // static | 260 // static |
| 366 scoped_refptr<SiteInstance> SiteInstance::Create( | 261 scoped_refptr<SiteInstance> SiteInstance::Create( |
| 367 BrowserContext* browser_context) { | 262 BrowserContext* browser_context) { |
| 368 return SiteInstanceImpl::Create(browser_context); | 263 return SiteInstanceImpl::Create(browser_context); |
| 369 } | 264 } |
| 370 | 265 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 browsing_instance_->browser_context(), site_)) | 418 browsing_instance_->browser_context(), site_)) |
| 524 return; | 419 return; |
| 525 | 420 |
| 526 ChildProcessSecurityPolicyImpl* policy = | 421 ChildProcessSecurityPolicyImpl* policy = |
| 527 ChildProcessSecurityPolicyImpl::GetInstance(); | 422 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 528 policy->LockToOrigin(process_->GetID(), site_); | 423 policy->LockToOrigin(process_->GetID(), site_); |
| 529 } | 424 } |
| 530 } | 425 } |
| 531 | 426 |
| 532 } // namespace content | 427 } // namespace content |
| OLD | NEW |