Home | History | Annotate | Download | only in browser
      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