Change UnmatchedServiceWorkerProcessTracker to handle default SiteInstance.
- Added code that enables the default SiteInstance to use an unmatched
service worker process for a site that is handled by the default SiteInstance.
- Remove default SiteInstance specific conditions from tests that were
testing process reuse and unmatched service worker process behavior.
- Added code to BrowsingInstance that tracks what site URLs are associated
with its default SiteInstance. This allows process reuse to be constrained
to sites explicitly associated with a specific default SiteInstance.
Bug: 958060
Change-Id: I9ce95dbd5ecc192cba8cd4e6046787d248ff3532
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1668449
Reviewed-by: Charlie Reis <[email protected]>
Commit-Queue: Aaron Colwell <[email protected]>
Cr-Commit-Position: refs/heads/master@{#672681}
diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc
index cfcf10a6..f8f9c56 100644
--- a/content/browser/browsing_instance.cc
+++ b/content/browser/browsing_instance.cc
@@ -55,6 +55,10 @@
return site_instance != nullptr && site_instance == default_site_instance_;
}
+bool BrowsingInstance::IsSiteInDefaultSiteInstance(const GURL& site_url) const {
+ return site_url_set_.find(site_url) != site_url_set_.end();
+}
+
bool BrowsingInstance::HasSiteInstance(const GURL& url) {
std::string site = GetSiteForURL(url).possibly_invalid_spec();
return site_instance_map_.find(site) != site_instance_map_.end();
@@ -100,8 +104,8 @@
scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURLHelper(
const GURL& url,
bool allow_default_instance) {
- std::string site = GetSiteForURL(url).possibly_invalid_spec();
- auto i = site_instance_map_.find(site);
+ const GURL site_url = GetSiteForURL(url);
+ auto i = site_instance_map_.find(site_url.possibly_invalid_spec());
if (i != site_instance_map_.end())
return i->second;
@@ -132,6 +136,10 @@
site_instance->SetSite(SiteInstanceImpl::GetDefaultSiteURL());
}
+
+ // Add |site_url| to the set so we can keep track of all the sites the
+ // the default SiteInstance has been returned for.
+ site_url_set_.insert(site_url);
return site_instance;
}
diff --git a/content/browser/browsing_instance.h b/content/browser/browsing_instance.h
index 775b64a8..acbf074 100644
--- a/content/browser/browsing_instance.h
+++ b/content/browser/browsing_instance.h
@@ -161,6 +161,14 @@
bool IsDefaultSiteInstance(const SiteInstanceImpl* site_instance) const;
+ // Returns true if |site_url| has been used to get a SiteInstance from this
+ // object and the default SiteInstance was returned. This simply indicates
+ // the site may be directed to the default SiteInstance process, but it does
+ // not indicate that the site has already been committed to that process.
+ // Returns false if no request for |site_url| has resulted in this object
+ // returning the default SiteInstance.
+ bool IsSiteInDefaultSiteInstance(const GURL& site_url) const;
+
// Helper function used by other methods in this class to ensure consistent
// mapping between |url| and site URL.
// Note: This should not be used by code outside this class.
@@ -207,6 +215,10 @@
// BrowsingInstance and the SiteInstanceImpl.
SiteInstanceImpl* default_site_instance_;
+ // Keeps track of the site URLs that this object mapped to the
+ // |default_site_instance_|.
+ std::set<GURL> site_url_set_;
+
DISALLOW_COPY_AND_ASSIGN(BrowsingInstance);
};
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index e43d9c4..4d29fc4 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1012,6 +1012,10 @@
}
private:
+ using ProcessID = int;
+ using SiteProcessIDPair = std::pair<GURL, ProcessID>;
+ using SiteProcessIDPairSet = std::set<SiteProcessIDPair>;
+
void RegisterProcessForSite(RenderProcessHost* host,
SiteInstanceImpl* site_instance) {
if (!HasProcess(host))
@@ -1022,7 +1026,15 @@
RenderProcessHost* TakeFreshestProcessForSite(
SiteInstanceImpl* site_instance) {
- RenderProcessHost* host = FindFreshestProcessForSite(site_instance);
+ SiteProcessIDPair site_process_pair =
+ FindFreshestProcessForSite(site_instance);
+
+ if (site_process_pair.first.is_empty())
+ return nullptr;
+
+ RenderProcessHost* host =
+ RenderProcessHost::FromID(site_process_pair.second);
+
if (!host)
return nullptr;
@@ -1037,20 +1049,31 @@
site_url, site_instance->lock_url()))
return nullptr;
- site_process_set_.erase(SiteProcessIDPair(site_url, host->GetID()));
+ site_process_set_.erase(site_process_pair);
if (!HasProcess(host))
host->RemoveObserver(this);
return host;
}
- RenderProcessHost* FindFreshestProcessForSite(
+ SiteProcessIDPair FindFreshestProcessForSite(
SiteInstanceImpl* site_instance) const {
- GURL site_url(site_instance->GetSiteURL());
- for (const auto& site_process_pair : base::Reversed(site_process_set_)) {
- if (site_process_pair.first == site_url)
- return RenderProcessHost::FromID(site_process_pair.second);
+ const auto reversed_site_process_set = base::Reversed(site_process_set_);
+ if (site_instance->IsDefaultSiteInstance()) {
+ // See if we can find an entry that maps to a site associated with the
+ // default SiteInstance. This allows the default SiteInstance to reuse a
+ // service worker process for any site that has been associated with it.
+ for (const auto& site_process_pair : reversed_site_process_set) {
+ if (site_instance->IsSiteInDefaultSiteInstance(site_process_pair.first))
+ return site_process_pair;
+ }
+ } else {
+ const GURL site_url(site_instance->GetSiteURL());
+ for (const auto& site_process_pair : reversed_site_process_set) {
+ if (site_process_pair.first == site_url)
+ return site_process_pair;
+ }
}
- return nullptr;
+ return SiteProcessIDPair();
}
// Returns true if this tracker contains the process ID |host->GetID()|.
@@ -1063,10 +1086,6 @@
return false;
}
- using ProcessID = int;
- using SiteProcessIDPair = std::pair<GURL, ProcessID>;
- using SiteProcessIDPairSet = std::set<SiteProcessIDPair>;
-
// Use std::set because duplicates don't need to be tracked separately (eg.,
// service workers for the same site in the same process). It is sorted in the
// order of insertion.
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc
index 560fa2a..8c428a55 100644
--- a/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -197,14 +197,7 @@
// the newest unmatched service worker's process (i.e., sw_host2).
scoped_refptr<SiteInstanceImpl> site_instance1 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(site_instance1->IsDefaultSiteInstance());
- // TODO(acolwell): Remove once CreateForServiceWorker() can return a
- // default SiteInstance.
- EXPECT_NE(sw_host2, site_instance1->GetProcess());
- } else {
- EXPECT_EQ(sw_host2, site_instance1->GetProcess());
- }
+ EXPECT_EQ(sw_host2, site_instance1->GetProcess());
// Getting a RenderProcessHost for a navigation to the same site must reuse
// the newest unmatched service worker's process (i.e., sw_host1). sw_host2
@@ -212,25 +205,14 @@
// with a corresponding unmatched service worker.
scoped_refptr<SiteInstanceImpl> site_instance2 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(site_instance2->IsDefaultSiteInstance());
- // TODO(acolwell): Remove once CreateForServiceWorker() can return a
- // default SiteInstance.
- EXPECT_NE(sw_host1, site_instance2->GetProcess());
- } else {
- EXPECT_EQ(sw_host1, site_instance2->GetProcess());
- }
+ EXPECT_EQ(sw_host1, site_instance2->GetProcess());
// Getting a RenderProcessHost for a navigation should return a new process
// because there is no unmatched service worker's process.
scoped_refptr<SiteInstanceImpl> site_instance3 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(site_instance3->IsDefaultSiteInstance());
- } else {
- EXPECT_NE(sw_host1, site_instance3->GetProcess());
- EXPECT_NE(sw_host2, site_instance3->GetProcess());
- }
+ EXPECT_NE(sw_host1, site_instance3->GetProcess());
+ EXPECT_NE(sw_host2, site_instance3->GetProcess());
}
class UnsuitableHostContentBrowserClient : public ContentBrowserClient {
@@ -322,14 +304,7 @@
// the newest unmatched service worker's process (i.e., sw_host2).
scoped_refptr<SiteInstanceImpl> site_instance1 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(site_instance1->IsDefaultSiteInstance());
- // TODO(acolwell): Remove once CreateForServiceWorker() can return
- // a default SiteInstance.
- EXPECT_NE(sw_host2, site_instance1->GetProcess());
- } else {
- EXPECT_EQ(sw_host2, site_instance1->GetProcess());
- }
+ EXPECT_EQ(sw_host2, site_instance1->GetProcess());
// Getting a RenderProcessHost for a navigation to the same site must reuse
// the newest unmatched service worker's process (i.e., sw_host1). sw_host2
@@ -337,14 +312,7 @@
// with a corresponding unmatched service worker.
scoped_refptr<SiteInstanceImpl> site_instance2 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(site_instance2->IsDefaultSiteInstance());
- // TODO(acolwell): Remove once CreateForServiceWorker() can return
- // a default SiteInstance.
- EXPECT_NE(sw_host1, site_instance2->GetProcess());
- } else {
- EXPECT_EQ(sw_host1, site_instance2->GetProcess());
- }
+ EXPECT_EQ(sw_host1, site_instance2->GetProcess());
}
TEST_F(RenderProcessHostUnitTest,
@@ -370,28 +338,14 @@
scoped_refptr<SiteInstanceImpl> sw_site_instance3 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
RenderProcessHost* sw_host3 = sw_site_instance3->GetProcess();
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(sw_site_instance3->IsDefaultSiteInstance());
- // TODO(acolwell: Remove once CreateForServiceWorker() can return a
- // default SiteInstance.
- EXPECT_NE(sw_host1, sw_host3);
- } else {
- EXPECT_EQ(sw_host1, sw_host3);
- }
+ EXPECT_EQ(sw_host1, sw_host3);
// Getting a RenderProcessHost for a navigation to the same site again with
// process-per-site flag should reuse the unmatched service worker's process.
scoped_refptr<SiteInstanceImpl> sw_site_instance4 =
SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
RenderProcessHost* sw_host4 = sw_site_instance4->GetProcess();
- if (AreDefaultSiteInstancesEnabled()) {
- EXPECT_TRUE(sw_site_instance4->IsDefaultSiteInstance());
- // TODO(acolwell: Remove once CreateForServiceWorker() can return a
- // default SiteInstance.
- EXPECT_NE(sw_host1, sw_host4);
- } else {
- EXPECT_EQ(sw_host1, sw_host4);
- }
+ EXPECT_EQ(sw_host1, sw_host4);
}
TEST_F(RenderProcessHostUnitTest, DoNotReuseOtherSiteServiceWorkerProcess) {
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index f346b89..e7fadf3 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -194,10 +194,14 @@
return browsing_instance_->default_process();
}
-bool SiteInstanceImpl::IsDefaultSiteInstance() {
+bool SiteInstanceImpl::IsDefaultSiteInstance() const {
return browsing_instance_->IsDefaultSiteInstance(this);
}
+bool SiteInstanceImpl::IsSiteInDefaultSiteInstance(const GURL& site_url) const {
+ return browsing_instance_->IsSiteInDefaultSiteInstance(site_url);
+}
+
void SiteInstanceImpl::MaybeSetBrowsingInstanceDefaultProcess() {
if (!base::FeatureList::IsEnabled(
features::kProcessSharingWithStrictSiteInstances)) {
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index b1f7dc24..5f57cd4 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -307,7 +307,11 @@
RenderProcessHost* GetDefaultProcessIfUsable();
// Returns true if this object was constructed as a default site instance.
- bool IsDefaultSiteInstance();
+ bool IsDefaultSiteInstance() const;
+
+ // Returns true if |site_url| is a site URL that the BrowsingInstance has
+ // associated with its default SiteInstance.
+ bool IsSiteInDefaultSiteInstance(const GURL& site_url) const;
// Returns true if the the site URL for |url| matches the site URL
// for this instance (i.e. GetSiteURL()). Otherwise returns false.