1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/site_details.h"
7 #include "base/metrics/histogram.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/render_process_host.h"
11 using content::BrowserThread
;
12 using content::RenderProcessHost
;
13 using content::SiteInstance
;
14 using content::WebContents
;
16 SiteData::SiteData() {}
18 SiteData::~SiteData() {}
20 SiteDetails::SiteDetails() {}
22 SiteDetails::~SiteDetails() {}
24 void SiteDetails::CollectSiteInfo(WebContents
* contents
,
25 SiteData
* site_data
) {
26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
27 content::BrowserContext
* browser_context
= contents
->GetBrowserContext();
29 // Find the BrowsingInstance this WebContents belongs to by iterating over
30 // the "primary" SiteInstances of each BrowsingInstance we've seen so far.
31 SiteInstance
* instance
= contents
->GetSiteInstance();
32 SiteInstance
* primary
= NULL
;
33 for (size_t i
= 0; i
< site_data
->instances
.size(); ++i
) {
34 if (instance
->IsRelatedSiteInstance(site_data
->instances
[i
])) {
35 primary
= site_data
->instances
[i
];
40 // Remember this as the "primary" SiteInstance of a new BrowsingInstance.
42 site_data
->instances
.push_back(instance
);
45 // Now keep track of how many sites we have in this BrowsingInstance (and
46 // overall), including sites in iframes.
47 std::set
<GURL
> sites_in_tab
= contents
->GetSitesInTab();
48 for (std::set
<GURL
>::iterator iter
= sites_in_tab
.begin();
49 iter
!= sites_in_tab
.end(); ++iter
) {
50 // Skip about:blank, since we won't usually give it its own process.
51 // Because about:blank has no host, its site URL will be blank.
55 // Make sure we don't overcount process-per-site sites, like the NTP.
56 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context
, *iter
) &&
57 site_data
->sites
.find(*iter
) != site_data
->sites
.end()) {
61 site_data
->sites
.insert(*iter
);
62 site_data
->instance_site_map
[primary
->GetId()].insert(*iter
);
64 // Also keep track of how things would look if we only isolated HTTPS sites.
65 // In this model, all HTTP sites are grouped into one "http://" site. HTTPS
66 // and other schemes (e.g., chrome:) are still isolated.
67 GURL https_site
= iter
->SchemeIs("http") ? GURL("http://") : *iter
;
68 site_data
->https_sites
.insert(https_site
);
69 site_data
->instance_https_site_map
[primary
->GetId()].insert(https_site
);
73 void SiteDetails::UpdateHistograms(
74 const BrowserContextSiteDataMap
& site_data_map
,
75 int all_renderer_process_count
,
76 int non_renderer_process_count
) {
77 // Reports a set of site-based process metrics to UMA.
78 int process_limit
= RenderProcessHost::GetMaxRendererProcessCount();
80 // Sum the number of sites and SiteInstances in each BrowserContext.
82 int num_https_sites
= 0;
83 int num_browsing_instances
= 0;
84 int num_isolated_site_instances
= 0;
85 int num_isolated_https_site_instances
= 0;
86 for (BrowserContextSiteDataMap::const_iterator i
= site_data_map
.begin();
87 i
!= site_data_map
.end(); ++i
) {
88 num_sites
+= i
->second
.sites
.size();
89 num_https_sites
+= i
->second
.https_sites
.size();
90 num_browsing_instances
+= i
->second
.instance_site_map
.size();
91 for (BrowsingInstanceSiteMap::const_iterator iter
=
92 i
->second
.instance_site_map
.begin();
93 iter
!= i
->second
.instance_site_map
.end(); ++iter
) {
94 num_isolated_site_instances
+= iter
->second
.size();
96 for (BrowsingInstanceSiteMap::const_iterator iter
=
97 i
->second
.instance_https_site_map
.begin();
98 iter
!= i
->second
.instance_https_site_map
.end(); ++iter
) {
99 num_isolated_https_site_instances
+= iter
->second
.size();
103 // Predict the number of processes needed when isolating all sites and when
104 // isolating only HTTPS sites.
105 int process_count_lower_bound
= num_sites
;
106 int process_count_upper_bound
= num_sites
+ process_limit
- 1;
107 int process_count_estimate
= std::min(
108 num_isolated_site_instances
, process_count_upper_bound
);
110 int process_count_https_lower_bound
= num_https_sites
;
111 int process_count_https_upper_bound
= num_https_sites
+ process_limit
- 1;
112 int process_count_https_estimate
= std::min(
113 num_isolated_https_site_instances
, process_count_https_upper_bound
);
115 // Just renderer process count:
116 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount",
117 all_renderer_process_count
);
118 UMA_HISTOGRAM_COUNTS_100(
119 "SiteIsolation.BrowsingInstanceCount",
120 num_browsing_instances
);
121 UMA_HISTOGRAM_COUNTS_100(
122 "SiteIsolation.IsolateAllSitesProcessCountNoLimit",
123 num_isolated_site_instances
);
124 UMA_HISTOGRAM_COUNTS_100(
125 "SiteIsolation.IsolateAllSitesProcessCountLowerBound",
126 process_count_lower_bound
);
127 UMA_HISTOGRAM_COUNTS_100(
128 "SiteIsolation.IsolateAllSitesProcessCountEstimate",
129 process_count_estimate
);
130 UMA_HISTOGRAM_COUNTS_100(
131 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit",
132 num_isolated_https_site_instances
);
133 UMA_HISTOGRAM_COUNTS_100(
134 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound",
135 process_count_https_lower_bound
);
136 UMA_HISTOGRAM_COUNTS_100(
137 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate",
138 process_count_https_estimate
);
140 // Total process count:
141 UMA_HISTOGRAM_COUNTS_100(
142 "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate",
143 process_count_estimate
+ non_renderer_process_count
);
144 UMA_HISTOGRAM_COUNTS_100(
145 "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate",
146 process_count_https_estimate
+ non_renderer_process_count
);