Chromium Code Reviews| 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, |
|
Lei Zhang
2015/10/30 07:17:49
const IsolationScenario*
ncarter (slow)
2015/10/30 18:13:24
Done.
| |
| 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 // Walk the frame tree and update |scenario|'s data for the given frame. Memoize | |
|
Lei Zhang
2015/10/30 07:17:49
typo: Memoize
ncarter (slow)
2015/10/30 18:13:24
Not a typo. Memoize is what I meant. https://en.wi
| |
| 60 // each frame's computed URL in |frame_urls| so it can be reused when visiting | |
| 61 // its children. | |
| 62 void CollectForScenario(std::map<RenderFrameHost*, GURL>* frame_urls, | |
| 63 SiteInstance* primary, | |
| 64 IsolationScenario* scenario, | |
| 65 RenderFrameHost* frame) { | |
| 66 BrowserContext* context = primary->GetBrowserContext(); | |
| 67 | |
| 68 GURL url = frame->GetLastCommittedURL(); | |
| 69 | |
| 70 // Treat about:blank url specially: use the URL on the SiteInstance if it is | |
| 71 // assigned. The rest of this computation must not depend on the | |
| 72 // SiteInstance's URL, since its value reflects the current process model, and | |
| 73 // this computation is simulating other process models. | |
| 74 if (url == GURL(url::kAboutBlankURL) && | |
| 75 frame->GetSiteInstance()->GetSiteURL() != GURL()) { | |
|
Lei Zhang
2015/10/30 07:17:49
Can you call GURL::is_empty() instead?
ncarter (slow)
2015/10/30 18:13:24
Done.
| |
| 76 url = frame->GetSiteInstance()->GetSiteURL(); | |
| 77 } | |
| 78 | |
| 79 GURL site = SiteInstance::GetSiteForURL(context, url); | |
| 80 bool should_isolate = ShouldIsolate(context, scenario, site); | |
| 81 | |
| 82 // Treat a subframe as part of its parent site if neither needs isolation. | |
| 83 if (frame->GetParent()) { | |
| 84 GURL parent_site = (*frame_urls)[frame->GetParent()]; | |
| 85 if (!should_isolate && !ShouldIsolate(context, scenario, parent_site)) | |
|
Lei Zhang
2015/10/30 07:17:49
Move the |should_isolate| check up 2 lines?
ncarter (slow)
2015/10/30 18:13:24
Done.
| |
| 86 site = parent_site; | |
| 87 } | |
| 88 | |
| 89 bool process_per_site = | |
| 90 site.is_valid() && | |
| 91 RenderProcessHost::ShouldUseProcessPerSite(context, site); | |
| 92 | |
| 93 // If we don't need a dedicated process, and aren't living in a process- | |
| 94 // per-site process, we are nothing special: collapse our URL to a dummy | |
| 95 // site. | |
| 96 if (!process_per_site && !should_isolate) | |
| 97 site = GURL("http://"); | |
| 98 | |
| 99 // We model process-per-site by only inserting those sites into the first | |
| 100 // browsing instance in which they appear. | |
| 101 if (scenario->sites.insert(site).second || !process_per_site) | |
| 102 scenario->browsing_instance_site_map[primary->GetId()].insert(site); | |
| 103 | |
| 104 // Record our result in |frame_urls| for use by children. | |
| 105 (*frame_urls)[frame] = site; | |
| 106 } | |
| 107 | |
| 54 } // namespace | 108 } // namespace |
| 55 | 109 |
| 56 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES) {} | 110 IsolationScenario::IsolationScenario() : policy(ISOLATE_ALL_SITES) {} |
| 57 | 111 |
| 58 IsolationScenario::~IsolationScenario() {} | 112 IsolationScenario::~IsolationScenario() {} |
| 59 | 113 |
| 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() { | 114 SiteData::SiteData() { |
| 71 scenarios[ISOLATE_ALL_SITES].policy = ISOLATE_ALL_SITES; | 115 for (int i = 0; i <= ISOLATION_SCENARIO_LAST; i++) |
| 72 scenarios[ISOLATE_HTTPS_SITES].policy = ISOLATE_HTTPS_SITES; | 116 scenarios[i].policy = static_cast<IsolationScenarioType>(i); |
| 73 scenarios[ISOLATE_EXTENSIONS].policy = ISOLATE_EXTENSIONS; | |
| 74 } | 117 } |
| 75 | 118 |
| 76 SiteData::~SiteData() {} | 119 SiteData::~SiteData() {} |
| 77 | 120 |
| 78 SiteDetails::SiteDetails() {} | 121 SiteDetails::SiteDetails() {} |
| 79 | 122 |
| 80 SiteDetails::~SiteDetails() {} | 123 SiteDetails::~SiteDetails() {} |
| 81 | 124 |
| 82 void SiteDetails::CollectSiteInfo(WebContents* contents, | 125 void SiteDetails::CollectSiteInfo(WebContents* contents, |
| 83 SiteData* site_data) { | 126 SiteData* site_data) { |
| 84 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 127 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 85 content::BrowserContext* browser_context = contents->GetBrowserContext(); | |
| 86 | |
| 87 // Find the BrowsingInstance this WebContents belongs to by iterating over | 128 // Find the BrowsingInstance this WebContents belongs to by iterating over |
| 88 // the "primary" SiteInstances of each BrowsingInstance we've seen so far. | 129 // the "primary" SiteInstances of each BrowsingInstance we've seen so far. |
| 89 SiteInstance* instance = contents->GetSiteInstance(); | 130 SiteInstance* instance = contents->GetSiteInstance(); |
| 90 SiteInstance* primary = NULL; | 131 SiteInstance* primary = NULL; |
| 91 for (SiteInstance* already_collected_instance : site_data->instances) { | 132 for (SiteInstance* already_collected_instance : site_data->instances) { |
| 92 if (instance->IsRelatedSiteInstance(already_collected_instance)) { | 133 if (instance->IsRelatedSiteInstance(already_collected_instance)) { |
| 93 primary = already_collected_instance; | 134 primary = already_collected_instance; |
| 94 break; | 135 break; |
| 95 } | 136 } |
| 96 } | 137 } |
| 97 if (!primary) { | 138 if (!primary) { |
| 98 // Remember this as the "primary" SiteInstance of a new BrowsingInstance. | 139 // Remember this as the "primary" SiteInstance of a new BrowsingInstance. |
| 99 primary = instance; | 140 primary = instance; |
| 100 site_data->instances.push_back(instance); | 141 site_data->instances.push_back(instance); |
| 101 } | 142 } |
| 102 | 143 |
| 103 // Now keep track of how many sites we have in this BrowsingInstance (and | 144 // Now keep track of how many sites we have in this BrowsingInstance (and |
| 104 // overall), including sites in iframes. | 145 // overall), including sites in iframes. |
| 105 for (const GURL& site : contents->GetSitesInTab()) { | 146 for (IsolationScenario& scenario : site_data->scenarios) { |
| 106 // Make sure we don't overcount process-per-site sites, like the NTP or | 147 std::map<RenderFrameHost*, GURL> memo; |
| 107 // extensions, by skipping over them if they're already logged for | 148 contents->ForEachFrame( |
| 108 // ISOLATE_ALL_SITES. | 149 base::Bind(&CollectForScenario, base::Unretained(&memo), |
| 109 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site) && | 150 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 } | 151 } |
| 119 } | 152 } |
| 120 | 153 |
| 121 void SiteDetails::UpdateHistograms( | 154 void SiteDetails::UpdateHistograms( |
| 122 const BrowserContextSiteDataMap& site_data_map, | 155 const BrowserContextSiteDataMap& site_data_map, |
| 123 int all_renderer_process_count, | 156 int all_renderer_process_count, |
| 124 int non_renderer_process_count) { | 157 int non_renderer_process_count) { |
| 125 // Reports a set of site-based process metrics to UMA. | 158 // Reports a set of site-based process metrics to UMA. |
| 126 int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); | 159 int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); |
| 127 | 160 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 153 process_count_estimate[policy] = std::min( | 186 process_count_estimate[policy] = std::min( |
| 154 num_isolated_site_instances[policy], process_count_upper_bound[policy]); | 187 num_isolated_site_instances[policy], process_count_upper_bound[policy]); |
| 155 } | 188 } |
| 156 | 189 |
| 157 // Just renderer process count: | 190 // Just renderer process count: |
| 158 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", | 191 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", |
| 159 all_renderer_process_count); | 192 all_renderer_process_count); |
| 160 UMA_HISTOGRAM_COUNTS_100( | 193 UMA_HISTOGRAM_COUNTS_100( |
| 161 "SiteIsolation.BrowsingInstanceCount", | 194 "SiteIsolation.BrowsingInstanceCount", |
| 162 num_browsing_instances); | 195 num_browsing_instances); |
| 196 | |
| 197 // ISOLATE_NOTHING metrics. | |
| 198 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountNoLimit", | |
| 199 num_isolated_site_instances[ISOLATE_NOTHING]); | |
| 200 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountLowerBound", | |
| 201 process_count_lower_bound[ISOLATE_NOTHING]); | |
| 202 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateNothingProcessCountEstimate", | |
| 203 process_count_estimate[ISOLATE_NOTHING]); | |
| 204 UMA_HISTOGRAM_COUNTS_100( | |
| 205 "SiteIsolation.IsolateNothingTotalProcessCountEstimate", | |
| 206 process_count_estimate[ISOLATE_NOTHING] + non_renderer_process_count); | |
| 207 | |
| 208 // ISOLATE_ALL_SITES metrics. | |
| 163 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountNoLimit", | 209 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountNoLimit", |
| 164 num_isolated_site_instances[ISOLATE_ALL_SITES]); | 210 num_isolated_site_instances[ISOLATE_ALL_SITES]); |
| 165 UMA_HISTOGRAM_COUNTS_100( | 211 UMA_HISTOGRAM_COUNTS_100( |
| 166 "SiteIsolation.IsolateAllSitesProcessCountLowerBound", | 212 "SiteIsolation.IsolateAllSitesProcessCountLowerBound", |
| 167 process_count_lower_bound[ISOLATE_ALL_SITES]); | 213 process_count_lower_bound[ISOLATE_ALL_SITES]); |
| 168 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountEstimate", | 214 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateAllSitesProcessCountEstimate", |
| 169 process_count_estimate[ISOLATE_ALL_SITES]); | 215 process_count_estimate[ISOLATE_ALL_SITES]); |
| 216 UMA_HISTOGRAM_COUNTS_100( | |
| 217 "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate", | |
| 218 process_count_estimate[ISOLATE_ALL_SITES] + non_renderer_process_count); | |
| 170 | 219 |
| 220 // ISOLATE_HTTPS_SITES metrics. | |
| 171 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", | 221 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", |
| 172 num_isolated_site_instances[ISOLATE_HTTPS_SITES]); | 222 num_isolated_site_instances[ISOLATE_HTTPS_SITES]); |
| 173 UMA_HISTOGRAM_COUNTS_100( | 223 UMA_HISTOGRAM_COUNTS_100( |
| 174 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", | 224 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", |
| 175 process_count_lower_bound[ISOLATE_HTTPS_SITES]); | 225 process_count_lower_bound[ISOLATE_HTTPS_SITES]); |
| 176 UMA_HISTOGRAM_COUNTS_100( | 226 UMA_HISTOGRAM_COUNTS_100( |
| 177 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", | 227 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", |
| 178 process_count_estimate[ISOLATE_HTTPS_SITES]); | 228 process_count_estimate[ISOLATE_HTTPS_SITES]); |
| 229 UMA_HISTOGRAM_COUNTS_100( | |
| 230 "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate", | |
| 231 process_count_estimate[ISOLATE_HTTPS_SITES] + non_renderer_process_count); | |
| 179 | 232 |
| 233 // ISOLATE_EXTENSIONS metrics. | |
| 180 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateExtensionsProcessCountNoLimit", | 234 UMA_HISTOGRAM_COUNTS_100("SiteIsolation.IsolateExtensionsProcessCountNoLimit", |
| 181 num_isolated_site_instances[ISOLATE_EXTENSIONS]); | 235 num_isolated_site_instances[ISOLATE_EXTENSIONS]); |
| 182 UMA_HISTOGRAM_COUNTS_100( | 236 UMA_HISTOGRAM_COUNTS_100( |
| 183 "SiteIsolation.IsolateExtensionsProcessCountLowerBound", | 237 "SiteIsolation.IsolateExtensionsProcessCountLowerBound", |
| 184 process_count_lower_bound[ISOLATE_EXTENSIONS]); | 238 process_count_lower_bound[ISOLATE_EXTENSIONS]); |
| 185 UMA_HISTOGRAM_COUNTS_100( | 239 UMA_HISTOGRAM_COUNTS_100( |
| 186 "SiteIsolation.IsolateExtensionsProcessCountEstimate", | 240 "SiteIsolation.IsolateExtensionsProcessCountEstimate", |
| 187 process_count_estimate[ISOLATE_EXTENSIONS]); | 241 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( | 242 UMA_HISTOGRAM_COUNTS_100( |
| 197 "SiteIsolation.IsolateExtensionsTotalProcessCountEstimate", | 243 "SiteIsolation.IsolateExtensionsTotalProcessCountEstimate", |
| 198 process_count_estimate[ISOLATE_EXTENSIONS] + non_renderer_process_count); | 244 process_count_estimate[ISOLATE_EXTENSIONS] + non_renderer_process_count); |
| 199 } | 245 } |
| OLD | NEW |