OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/site_details.h" | 5 #include "chrome/browser/site_details.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "content/public/browser/browser_thread.h" | 8 #include "content/public/browser/browser_thread.h" |
9 #include "content/public/browser/render_frame_host.h" | |
9 #include "content/public/browser/render_process_host.h" | 10 #include "content/public/browser/render_process_host.h" |
10 | 11 |
11 #if defined(ENABLE_EXTENSIONS) | 12 #if defined(ENABLE_EXTENSIONS) |
12 #include "extensions/browser/extension_registry.h" | 13 #include "extensions/browser/extension_registry.h" |
13 #include "extensions/common/constants.h" | 14 #include "extensions/common/constants.h" |
14 #include "extensions/common/extension.h" | 15 #include "extensions/common/extension.h" |
15 #endif | 16 #endif |
16 | 17 |
18 using content::BrowserContext; | |
17 using content::BrowserThread; | 19 using content::BrowserThread; |
20 using content::RenderFrameHost; | |
18 using content::RenderProcessHost; | 21 using content::RenderProcessHost; |
19 using content::SiteInstance; | 22 using content::SiteInstance; |
20 using content::WebContents; | 23 using content::WebContents; |
21 | 24 |
22 namespace { | 25 namespace { |
23 | 26 |
24 bool ShouldIsolate(content::BrowserContext* browser_context, | 27 bool ShouldIsolate(BrowserContext* browser_context, |
25 IsolationScenarioType policy, | 28 IsolationScenario* scenario, |
26 const GURL& site) { | 29 const GURL& site) { |
27 switch (policy) { | 30 switch (scenario->policy) { |
31 case ISOLATE_NOTHING: | |
32 return false; | |
28 case ISOLATE_ALL_SITES: | 33 case ISOLATE_ALL_SITES: |
29 return true; | 34 return true; |
30 case ISOLATE_HTTPS_SITES: | 35 case ISOLATE_HTTPS_SITES: |
31 // Note: For estimation purposes "isolate https sites" is really | 36 // Note: For estimation purposes "isolate https sites" is really |
32 // implemented as "isolate non-http sites". This means that, for example, | 37 // implemented as "isolate non-http sites". This means that, for example, |
33 // the New Tab Page gets counted as two processes under this policy, and | 38 // the New Tab Page gets counted as two processes under this policy, and |
34 // extensions are isolated as well. | 39 // extensions are isolated as well. |
35 return !site.SchemeIs(url::kHttpScheme); | 40 return !site.SchemeIs(url::kHttpScheme); |
36 case ISOLATE_EXTENSIONS: { | 41 case ISOLATE_EXTENSIONS: { |
37 #if !defined(ENABLE_EXTENSIONS) | 42 #if !defined(ENABLE_EXTENSIONS) |
38 return false; | 43 return false; |
39 #else | 44 #else |
40 if (!site.SchemeIs(extensions::kExtensionScheme)) | 45 if (!site.SchemeIs(extensions::kExtensionScheme)) |
41 return false; | 46 return false; |
42 extensions::ExtensionRegistry* registry = | 47 extensions::ExtensionRegistry* registry = |
43 extensions::ExtensionRegistry::Get(browser_context); | 48 extensions::ExtensionRegistry::Get(browser_context); |
44 const extensions::Extension* extension = | 49 const extensions::Extension* extension = |
45 registry->enabled_extensions().GetExtensionOrAppByURL(site); | 50 registry->enabled_extensions().GetExtensionOrAppByURL(site); |
46 return extension && !extension->is_hosted_app(); | 51 return extension && !extension->is_hosted_app(); |
47 #endif | 52 #endif |
48 } | 53 } |
49 } | 54 } |
50 NOTREACHED(); | 55 NOTREACHED(); |
51 return true; | 56 return true; |
52 } | 57 } |
53 | 58 |
59 void CollectForScenario(std::map<RenderFrameHost*, GURL>* memo, | |
Charlie Reis
2015/10/23 19:03:40
nit: memo -> frame_urls?
We could add a comment a
ncarter (slow)
2015/10/29 19:55:06
Done.
| |
60 SiteInstance* primary, | |
61 IsolationScenario* scenario, | |
62 RenderFrameHost* frame) { | |
63 BrowserContext* context = primary->GetBrowserContext(); | |
64 | |
65 GURL url = frame->GetLastCommittedURL(); | |
66 | |
67 // Treat about:blank url specially: use the URL on the SiteInstance if it is | |
68 // assigned. The rest of this computation must not depend on the | |
69 // SiteInstance's URL, since its value reflects the current process model, and | |
70 // this computation is simulating other process models. | |
71 if (url == GURL(url::kAboutBlankURL) && | |
72 frame->GetSiteInstance()->GetSiteURL() != GURL()) { | |
73 url = frame->GetSiteInstance()->GetSiteURL(); | |
74 } | |
75 | |
76 GURL site = SiteInstance::GetSiteForURL(context, url); | |
77 bool should_isolate = ShouldIsolate(context, scenario, site); | |
78 if (frame->GetParent()) { | |
Charlie Reis
2015/10/23 19:03:40
// Treat a subframe as part of its parent site if
ncarter (slow)
2015/10/29 19:55:06
Done.
| |
79 GURL parent_site = (*memo)[frame->GetParent()]; | |
80 if (!should_isolate && !ShouldIsolate(context, scenario, parent_site)) | |
81 site = parent_site; | |
82 } | |
83 | |
84 bool process_per_site = | |
85 site.is_valid() && | |
86 RenderProcessHost::ShouldUseProcessPerSite(context, site); | |
87 | |
88 // If we don't need a dedicated process, and aren't living it a process- | |
Charlie Reis
2015/10/23 19:03:40
nit: s/it/in/
ncarter (slow)
2015/10/29 19:55:06
Done.
| |
89 // per-site process, we are nothing special: collapse our URL to a dummy | |
90 // site. | |
91 if (!process_per_site && !should_isolate) | |
92 site = GURL("http://"); | |
93 | |
94 // We model process-per-site by only inserting those sites into the first | |
95 // browsing instance in which they appear. | |
96 if (scenario->sites.insert(site).second || !process_per_site) | |
97 scenario->browsing_instance_site_map[primary->GetId()].insert(site); | |
98 | |
99 // Record our result in |memo| for use by children. | |
100 (*memo)[frame] = site; | |
101 } | |
102 | |
54 } // namespace | 103 } // namespace |
55 | 104 |
56 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES) {} | 105 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES) {} |
57 | 106 |
58 IsolationScenario::~IsolationScenario() {} | 107 IsolationScenario::~IsolationScenario() {} |
59 | 108 |
60 void IsolationScenario::CollectSiteInfoForScenario(SiteInstance* primary, | |
61 const GURL& site) { | |
62 const GURL& isolated = | |
63 ShouldIsolate(primary->GetBrowserContext(), policy, site) | |
64 ? site | |
65 : GURL("http://"); | |
66 sites.insert(isolated); | |
67 browsing_instance_site_map[primary->GetId()].insert(isolated); | |
68 } | |
69 | |
70 SiteData::SiteData() { | 109 SiteData::SiteData() { |
71 scenarios[ISOLATE_ALL_SITES].policy = ISOLATE_ALL_SITES; | 110 for (int i = 0; i <= ISOLATION_SCENARIO_LAST; i++) |
72 scenarios[ISOLATE_HTTPS_SITES].policy = ISOLATE_HTTPS_SITES; | 111 scenarios[i].policy = static_cast<IsolationScenarioType>(i); |
73 scenarios[ISOLATE_EXTENSIONS].policy = ISOLATE_EXTENSIONS; | |
74 } | 112 } |
75 | 113 |
76 SiteData::~SiteData() {} | 114 SiteData::~SiteData() {} |
77 | 115 |
78 SiteDetails::SiteDetails() {} | 116 SiteDetails::SiteDetails() {} |
79 | 117 |
80 SiteDetails::~SiteDetails() {} | 118 SiteDetails::~SiteDetails() {} |
81 | 119 |
82 void SiteDetails::CollectSiteInfo(WebContents* contents, | 120 void SiteDetails::CollectSiteInfo(WebContents* contents, |
83 SiteData* site_data) { | 121 SiteData* site_data) { |
84 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 122 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
85 content::BrowserContext* browser_context = contents->GetBrowserContext(); | |
86 | |
87 // Find the BrowsingInstance this WebContents belongs to by iterating over | 123 // Find the BrowsingInstance this WebContents belongs to by iterating over |
88 // the "primary" SiteInstances of each BrowsingInstance we've seen so far. | 124 // the "primary" SiteInstances of each BrowsingInstance we've seen so far. |
89 SiteInstance* instance = contents->GetSiteInstance(); | 125 SiteInstance* instance = contents->GetSiteInstance(); |
90 SiteInstance* primary = NULL; | 126 SiteInstance* primary = NULL; |
91 for (SiteInstance* already_collected_instance : site_data->instances) { | 127 for (SiteInstance* already_collected_instance : site_data->instances) { |
92 if (instance->IsRelatedSiteInstance(already_collected_instance)) { | 128 if (instance->IsRelatedSiteInstance(already_collected_instance)) { |
93 primary = already_collected_instance; | 129 primary = already_collected_instance; |
94 break; | 130 break; |
95 } | 131 } |
96 } | 132 } |
97 if (!primary) { | 133 if (!primary) { |
98 // Remember this as the "primary" SiteInstance of a new BrowsingInstance. | 134 // Remember this as the "primary" SiteInstance of a new BrowsingInstance. |
99 primary = instance; | 135 primary = instance; |
100 site_data->instances.push_back(instance); | 136 site_data->instances.push_back(instance); |
101 } | 137 } |
102 | 138 |
103 // Now keep track of how many sites we have in this BrowsingInstance (and | 139 // Now keep track of how many sites we have in this BrowsingInstance (and |
104 // overall), including sites in iframes. | 140 // overall), including sites in iframes. |
105 for (const GURL& site : contents->GetSitesInTab()) { | 141 for (IsolationScenario& scenario : site_data->scenarios) { |
106 // Make sure we don't overcount process-per-site sites, like the NTP or | 142 std::map<RenderFrameHost*, GURL> memo; |
107 // extensions, by skipping over them if they're already logged for | 143 contents->ForEachFrame( |
108 // ISOLATE_ALL_SITES. | 144 base::Bind(&CollectForScenario, base::Unretained(&memo), |
109 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site) && | 145 base::Unretained(primary), base::Unretained(&scenario))); |
110 site_data->scenarios[ISOLATE_ALL_SITES].sites.find(site) != | |
111 site_data->scenarios[ISOLATE_ALL_SITES].sites.end()) { | |
112 continue; | |
113 } | |
114 | |
115 for (IsolationScenario& scenario : site_data->scenarios) { | |
116 scenario.CollectSiteInfoForScenario(primary, site); | |
117 } | |
118 } | 146 } |
119 } | 147 } |
120 | 148 |
121 void SiteDetails::UpdateHistograms( | 149 void SiteDetails::UpdateHistograms( |
122 const BrowserContextSiteDataMap& site_data_map, | 150 const BrowserContextSiteDataMap& site_data_map, |
123 int all_renderer_process_count, | 151 int all_renderer_process_count, |
124 int non_renderer_process_count) { | 152 int non_renderer_process_count) { |
125 // Reports a set of site-based process metrics to UMA. | 153 // Reports a set of site-based process metrics to UMA. |
126 int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); | 154 int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); |
127 | 155 |
(...skipping 25 matching lines...) Expand all Loading... | |
153 process_count_estimate[policy] = std::min( | 181 process_count_estimate[policy] = std::min( |
154 num_isolated_site_instances[policy], process_count_upper_bound[policy]); | 182 num_isolated_site_instances[policy], process_count_upper_bound[policy]); |
155 } | 183 } |
156 | 184 |
157 // Just renderer process count: | 185 // Just renderer process count: |
158 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", | 186 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", |
159 all_renderer_process_count); | 187 all_renderer_process_count); |
160 UMA_HISTOGRAM_COUNTS_100( | 188 UMA_HISTOGRAM_COUNTS_100( |
161 "SiteIsolation.BrowsingInstanceCount", | 189 "SiteIsolation.BrowsingInstanceCount", |
162 num_browsing_instances); | 190 num_browsing_instances); |
191 | |
192 // ISOLATE_NOTHING metrics. | |
193 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountNoLimit", | |
194 num_isolated_site_instances[ISOLATE_NOTHING]); | |
195 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountLowerBound", | |
196 process_count_lower_bound[ISOLATE_NOTHING]); | |
197 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountEstimate", | |
198 process_count_estimate[ISOLATE_NOTHING]); | |
199 UMA_HISTOGRAM_COUNTS_100( | |
200 "SiteIsolation.IsolateNothingTotalProcessCountEstimate", | |
201 process_count_estimate[ISOLATE_NOTHING] + non_renderer_process_count); | |
202 | |
203 // ISOLATE_ALL_SITES metrics. | |
163 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountNoLimit", | 204 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountNoLimit", |
164 num_isolated_site_instances[ISOLATE_ALL_SITES]); | 205 num_isolated_site_instances[ISOLATE_ALL_SITES]); |
165 UMA_HISTOGRAM_COUNTS_100( | 206 UMA_HISTOGRAM_COUNTS_100( |
166 "SiteIsolation.IsolateAllSitesProcessCountLowerBound", | 207 "SiteIsolation.IsolateAllSitesProcessCountLowerBound", |
167 process_count_lower_bound[ISOLATE_ALL_SITES]); | 208 process_count_lower_bound[ISOLATE_ALL_SITES]); |
168 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountEstimate", | 209 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountEstimate", |
169 process_count_estimate[ISOLATE_ALL_SITES]); | 210 process_count_estimate[ISOLATE_ALL_SITES]); |
211 UMA_HISTOGRAM_COUNTS_100( | |
212 "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate", | |
213 process_count_estimate[ISOLATE_ALL_SITES] + non_renderer_process_count); | |
170 | 214 |
215 // ISOLATE_HTTPS_SITES metrics. | |
171 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", | 216 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", |
172 num_isolated_site_instances[ISOLATE_HTTPS_SITES]); | 217 num_isolated_site_instances[ISOLATE_HTTPS_SITES]); |
173 UMA_HISTOGRAM_COUNTS_100( | 218 UMA_HISTOGRAM_COUNTS_100( |
174 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", | 219 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", |
175 process_count_lower_bound[ISOLATE_HTTPS_SITES]); | 220 process_count_lower_bound[ISOLATE_HTTPS_SITES]); |
176 UMA_HISTOGRAM_COUNTS_100( | 221 UMA_HISTOGRAM_COUNTS_100( |
177 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", | 222 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", |
178 process_count_estimate[ISOLATE_HTTPS_SITES]); | 223 process_count_estimate[ISOLATE_HTTPS_SITES]); |
224 UMA_HISTOGRAM_COUNTS_100( | |
225 "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate", | |
226 process_count_estimate[ISOLATE_HTTPS_SITES] + non_renderer_process_count); | |
179 | 227 |
228 // ISOLATE_EXTENSIONS metrics. | |
180 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateExtensionsProcessCountNoLimit", | 229 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateExtensionsProcessCountNoLimit", |
181 num_isolated_site_instances[ISOLATE_EXTENSIONS]); | 230 num_isolated_site_instances[ISOLATE_EXTENSIONS]); |
182 UMA_HISTOGRAM_COUNTS_100( | 231 UMA_HISTOGRAM_COUNTS_100( |
183 "SiteIsolation.IsolateExtensionsProcessCountLowerBound", | 232 "SiteIsolation.IsolateExtensionsProcessCountLowerBound", |
184 process_count_lower_bound[ISOLATE_EXTENSIONS]); | 233 process_count_lower_bound[ISOLATE_EXTENSIONS]); |
185 UMA_HISTOGRAM_COUNTS_100( | 234 UMA_HISTOGRAM_COUNTS_100( |
186 "SiteIsolation.IsolateExtensionsProcessCountEstimate", | 235 "SiteIsolation.IsolateExtensionsProcessCountEstimate", |
187 process_count_estimate[ISOLATE_EXTENSIONS]); | 236 process_count_estimate[ISOLATE_EXTENSIONS]); |
188 | |
189 // Total process count: | |
190 UMA_HISTOGRAM_COUNTS_100( | |
191 "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate", | |
192 process_count_estimate[ISOLATE_ALL_SITES] + non_renderer_process_count); | |
193 UMA_HISTOGRAM_COUNTS_100( | |
194 "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate", | |
195 process_count_estimate[ISOLATE_HTTPS_SITES] + non_renderer_process_count); | |
196 UMA_HISTOGRAM_COUNTS_100( | 237 UMA_HISTOGRAM_COUNTS_100( |
197 "SiteIsolation.IsolateExtensionsTotalProcessCountEstimate", | 238 "SiteIsolation.IsolateExtensionsTotalProcessCountEstimate", |
198 process_count_estimate[ISOLATE_EXTENSIONS] + non_renderer_process_count); | 239 process_count_estimate[ISOLATE_EXTENSIONS] + non_renderer_process_count); |
199 } | 240 } |
OLD | NEW |