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. 4 5 #include "chrome/browser/site_details.h" 6 7 #include "base/metrics/histogram.h" 8 #include "content/public/browser/browser_thread.h" 9 #include "content/public/browser/render_process_host.h" 10 11 using content::BrowserThread; 12 using content::RenderProcessHost; 13 using content::SiteInstance; 14 using content::WebContents; 15 16 SiteData::SiteData() {} 17 18 SiteData::~SiteData() {} 19 20 SiteDetails::SiteDetails() {} 21 22 SiteDetails::~SiteDetails() {} 23 24 void SiteDetails::CollectSiteInfo(WebContents* contents, 25 SiteData* site_data) { 26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 27 content::BrowserContext* browser_context = contents->GetBrowserContext(); 28 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]; 36 break; 37 } 38 } 39 if (!primary) { 40 // Remember this as the "primary" SiteInstance of a new BrowsingInstance. 41 primary = instance; 42 site_data->instances.push_back(instance); 43 } 44 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. 52 if (iter->is_empty()) 53 continue; 54 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()) { 58 continue; 59 } 60 61 site_data->sites.insert(*iter); 62 site_data->instance_site_map[primary->GetId()].insert(*iter); 63 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); 70 } 71 } 72 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(); 79 80 // Sum the number of sites and SiteInstances in each BrowserContext. 81 int num_sites = 0; 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(); 95 } 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(); 100 } 101 } 102 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); 109 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); 114 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); 139 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); 147 } 148