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"
10 #include "extensions/common/constants.h"
12 using content::BrowserThread
;
13 using content::RenderProcessHost
;
14 using content::SiteInstance
;
15 using content::WebContents
;
19 bool ShouldIsolate(IsolationScenarioType policy
, const GURL
& site
) {
21 case ISOLATE_ALL_SITES
:
23 case ISOLATE_HTTPS_SITES
:
24 // Note: For estimation purposes "isolate https sites" is really
25 // implemented as "isolate non-http sites". This means that, for example,
26 // the New Tab Page gets counted as two processes under this policy, and
27 // extensions are isolated as well.
28 return !site
.SchemeIs(url::kHttpScheme
);
29 case ISOLATE_EXTENSIONS
:
30 return site
.SchemeIs(extensions::kExtensionScheme
);
38 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES
) {}
40 IsolationScenario::~IsolationScenario() {}
42 void IsolationScenario::CollectSiteInfoForScenario(SiteInstance
* primary
,
44 const GURL
& isolated
= ShouldIsolate(policy
, site
) ? site
: GURL("http://");
45 sites
.insert(isolated
);
46 browsing_instance_site_map
[primary
->GetId()].insert(isolated
);
49 SiteData::SiteData() {
50 scenarios
[ISOLATE_ALL_SITES
].policy
= ISOLATE_ALL_SITES
;
51 scenarios
[ISOLATE_HTTPS_SITES
].policy
= ISOLATE_HTTPS_SITES
;
52 scenarios
[ISOLATE_EXTENSIONS
].policy
= ISOLATE_EXTENSIONS
;
55 SiteData::~SiteData() {}
57 SiteDetails::SiteDetails() {}
59 SiteDetails::~SiteDetails() {}
61 void SiteDetails::CollectSiteInfo(WebContents
* contents
,
62 SiteData
* site_data
) {
63 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
64 content::BrowserContext
* browser_context
= contents
->GetBrowserContext();
66 // Find the BrowsingInstance this WebContents belongs to by iterating over
67 // the "primary" SiteInstances of each BrowsingInstance we've seen so far.
68 SiteInstance
* instance
= contents
->GetSiteInstance();
69 SiteInstance
* primary
= NULL
;
70 for (SiteInstance
* already_collected_instance
: site_data
->instances
) {
71 if (instance
->IsRelatedSiteInstance(already_collected_instance
)) {
72 primary
= already_collected_instance
;
77 // Remember this as the "primary" SiteInstance of a new BrowsingInstance.
79 site_data
->instances
.push_back(instance
);
82 // Now keep track of how many sites we have in this BrowsingInstance (and
83 // overall), including sites in iframes.
84 for (const GURL
& site
: contents
->GetSitesInTab()) {
85 // Make sure we don't overcount process-per-site sites, like the NTP or
86 // extensions, by skipping over them if they're already logged for
88 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context
, site
) &&
89 site_data
->scenarios
[ISOLATE_ALL_SITES
].sites
.find(site
) !=
90 site_data
->scenarios
[ISOLATE_ALL_SITES
].sites
.end()) {
94 for (IsolationScenario
& scenario
: site_data
->scenarios
) {
95 scenario
.CollectSiteInfoForScenario(primary
, site
);
100 void SiteDetails::UpdateHistograms(
101 const BrowserContextSiteDataMap
& site_data_map
,
102 int all_renderer_process_count
,
103 int non_renderer_process_count
) {
104 // Reports a set of site-based process metrics to UMA.
105 int process_limit
= RenderProcessHost::GetMaxRendererProcessCount();
107 // Sum the number of sites and SiteInstances in each BrowserContext.
108 int num_sites
[ISOLATION_SCENARIO_LAST
+ 1] = {};
109 int num_isolated_site_instances
[ISOLATION_SCENARIO_LAST
+ 1] = {};
110 int num_browsing_instances
= 0;
111 for (BrowserContextSiteDataMap::const_iterator i
= site_data_map
.begin();
112 i
!= site_data_map
.end(); ++i
) {
113 for (const IsolationScenario
& scenario
: i
->second
.scenarios
) {
114 num_sites
[scenario
.policy
] += scenario
.sites
.size();
115 for (auto& browsing_instance
: scenario
.browsing_instance_site_map
) {
116 num_isolated_site_instances
[scenario
.policy
] +=
117 browsing_instance
.second
.size();
120 num_browsing_instances
+= i
->second
.scenarios
[ISOLATE_ALL_SITES
]
121 .browsing_instance_site_map
.size();
124 // Predict the number of processes needed when isolating all sites, when
125 // isolating only HTTPS sites, and when isolating extensions.
126 int process_count_lower_bound
[ISOLATION_SCENARIO_LAST
+ 1];
127 int process_count_upper_bound
[ISOLATION_SCENARIO_LAST
+ 1];
128 int process_count_estimate
[ISOLATION_SCENARIO_LAST
+ 1];
129 for (int policy
= 0; policy
<= ISOLATION_SCENARIO_LAST
; policy
++) {
130 process_count_lower_bound
[policy
] = num_sites
[policy
];
131 process_count_upper_bound
[policy
] = num_sites
[policy
] + process_limit
- 1;
132 process_count_estimate
[policy
] = std::min(
133 num_isolated_site_instances
[policy
], process_count_upper_bound
[policy
]);
136 // Just renderer process count:
137 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount",
138 all_renderer_process_count
);
139 UMA_HISTOGRAM_COUNTS_100(
140 "SiteIsolation.BrowsingInstanceCount",
141 num_browsing_instances
);
142 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountNoLimit",
143 num_isolated_site_instances
[ISOLATE_ALL_SITES
]);
144 UMA_HISTOGRAM_COUNTS_100(
145 "SiteIsolation.IsolateAllSitesProcessCountLowerBound",
146 process_count_lower_bound
[ISOLATE_ALL_SITES
]);
147 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountEstimate",
148 process_count_estimate
[ISOLATE_ALL_SITES
]);
150 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateHttpsSitesProcessCountNoLimit",
151 num_isolated_site_instances
[ISOLATE_HTTPS_SITES
]);
152 UMA_HISTOGRAM_COUNTS_100(
153 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound",
154 process_count_lower_bound
[ISOLATE_HTTPS_SITES
]);
155 UMA_HISTOGRAM_COUNTS_100(
156 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate",
157 process_count_estimate
[ISOLATE_HTTPS_SITES
]);
159 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateExtensionsProcessCountNoLimit",
160 num_isolated_site_instances
[ISOLATE_EXTENSIONS
]);
161 UMA_HISTOGRAM_COUNTS_100(
162 "SiteIsolation.IsolateExtensionsProcessCountLowerBound",
163 process_count_lower_bound
[ISOLATE_EXTENSIONS
]);
164 UMA_HISTOGRAM_COUNTS_100(
165 "SiteIsolation.IsolateExtensionsProcessCountEstimate",
166 process_count_estimate
[ISOLATE_EXTENSIONS
]);
168 // Total process count:
169 UMA_HISTOGRAM_COUNTS_100(
170 "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate",
171 process_count_estimate
[ISOLATE_ALL_SITES
] + non_renderer_process_count
);
172 UMA_HISTOGRAM_COUNTS_100(
173 "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate",
174 process_count_estimate
[ISOLATE_HTTPS_SITES
] + non_renderer_process_count
);
175 UMA_HISTOGRAM_COUNTS_100(
176 "SiteIsolation.IsolateExtensionsTotalProcessCountEstimate",
177 process_count_estimate
[ISOLATE_EXTENSIONS
] + non_renderer_process_count
);