17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/site_details.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/metrics/histogram.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::BrowserThread;
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::RenderProcessHost;
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::SiteInstance;
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::WebContents;
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SiteData::SiteData() {}
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SiteData::~SiteData() {}
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SiteDetails::SiteDetails() {}
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SiteDetails::~SiteDetails() {}
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SiteDetails::CollectSiteInfo(WebContents* contents,
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  SiteData* site_data) {
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::BrowserContext* browser_context = contents->GetBrowserContext();
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Find the BrowsingInstance this WebContents belongs to by iterating over
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the "primary" SiteInstances of each BrowsingInstance we've seen so far.
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SiteInstance* instance = contents->GetSiteInstance();
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SiteInstance* primary = NULL;
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (size_t i = 0; i < site_data->instances.size(); ++i) {
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (instance->IsRelatedSiteInstance(site_data->instances[i])) {
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      primary = site_data->instances[i];
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!primary) {
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Remember this as the "primary" SiteInstance of a new BrowsingInstance.
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    primary = instance;
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    site_data->instances.push_back(instance);
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Now keep track of how many sites we have in this BrowsingInstance (and
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // overall), including sites in iframes.
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::set<GURL> sites_in_tab = contents->GetSitesInTab();
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (std::set<GURL>::iterator iter = sites_in_tab.begin();
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       iter != sites_in_tab.end(); ++iter) {
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Skip about:blank, since we won't usually give it its own process.
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Because about:blank has no host, its site URL will be blank.
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (iter->is_empty())
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Make sure we don't overcount process-per-site sites, like the NTP.
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, *iter) &&
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        site_data->sites.find(*iter) != site_data->sites.end()) {
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    site_data->sites.insert(*iter);
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    site_data->instance_site_map[primary->GetId()].insert(*iter);
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Also keep track of how things would look if we only isolated HTTPS sites.
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // In this model, all HTTP sites are grouped into one "http://" site.  HTTPS
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // and other schemes (e.g., chrome:) are still isolated.
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    GURL https_site = iter->SchemeIs("http") ? GURL("http://") : *iter;
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    site_data->https_sites.insert(https_site);
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    site_data->instance_https_site_map[primary->GetId()].insert(https_site);
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SiteDetails::UpdateHistograms(
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const BrowserContextSiteDataMap& site_data_map,
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int all_renderer_process_count,
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int non_renderer_process_count) {
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Reports a set of site-based process metrics to UMA.
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_limit = RenderProcessHost::GetMaxRendererProcessCount();
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Sum the number of sites and SiteInstances in each BrowserContext.
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_sites = 0;
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_https_sites = 0;
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_browsing_instances = 0;
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_isolated_site_instances = 0;
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int num_isolated_https_site_instances = 0;
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (BrowserContextSiteDataMap::const_iterator i = site_data_map.begin();
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       i != site_data_map.end(); ++i) {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    num_sites += i->second.sites.size();
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    num_https_sites += i->second.https_sites.size();
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    num_browsing_instances += i->second.instance_site_map.size();
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (BrowsingInstanceSiteMap::const_iterator iter =
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             i->second.instance_site_map.begin();
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         iter != i->second.instance_site_map.end(); ++iter) {
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_site_instances += iter->second.size();
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (BrowsingInstanceSiteMap::const_iterator iter =
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             i->second.instance_https_site_map.begin();
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         iter != i->second.instance_https_site_map.end(); ++iter) {
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_https_site_instances += iter->second.size();
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Predict the number of processes needed when isolating all sites and when
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // isolating only HTTPS sites.
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_lower_bound = num_sites;
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_upper_bound = num_sites + process_limit - 1;
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_estimate = std::min(
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_site_instances, process_count_upper_bound);
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_https_lower_bound = num_https_sites;
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_https_upper_bound = num_https_sites + process_limit - 1;
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_count_https_estimate = std::min(
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_https_site_instances, process_count_https_upper_bound);
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Just renderer process count:
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount",
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           all_renderer_process_count);
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.BrowsingInstanceCount",
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_browsing_instances);
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateAllSitesProcessCountNoLimit",
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_site_instances);
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateAllSitesProcessCountLowerBound",
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_lower_bound);
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateAllSitesProcessCountEstimate",
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_estimate);
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit",
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      num_isolated_https_site_instances);
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound",
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_https_lower_bound);
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateHttpsSitesProcessCountEstimate",
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_https_estimate);
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Total process count:
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate",
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_estimate + non_renderer_process_count);
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100(
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate",
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      process_count_https_estimate + non_renderer_process_count);
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
148