1 // Copyright (c) 2012 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/ui/uma_browsing_activity_observer.h" 6 7 #include "base/metrics/histogram.h" 8 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/search_engines/template_url_service_factory.h" 10 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser_finder.h" 12 #include "chrome/browser/ui/browser_iterator.h" 13 #include "chrome/browser/ui/browser_window.h" 14 #include "chrome/browser/ui/tabs/tab_strip_model.h" 15 #include "components/search_engines/template_url_service.h" 16 #include "content/public/browser/navigation_controller.h" 17 #include "content/public/browser/navigation_details.h" 18 #include "content/public/browser/navigation_entry.h" 19 #include "content/public/browser/notification_service.h" 20 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/user_metrics.h" 22 23 namespace chrome { 24 namespace { 25 26 UMABrowsingActivityObserver* g_instance = NULL; 27 28 } // namespace 29 30 // static 31 void UMABrowsingActivityObserver::Init() { 32 DCHECK(!g_instance); 33 // Must be created before any Browsers are. 34 DCHECK_EQ(0U, chrome::GetTotalBrowserCount()); 35 g_instance = new UMABrowsingActivityObserver; 36 } 37 38 UMABrowsingActivityObserver::UMABrowsingActivityObserver() { 39 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 40 content::NotificationService::AllSources()); 41 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 42 content::NotificationService::AllSources()); 43 } 44 45 UMABrowsingActivityObserver::~UMABrowsingActivityObserver() { 46 } 47 48 void UMABrowsingActivityObserver::Observe( 49 int type, 50 const content::NotificationSource& source, 51 const content::NotificationDetails& details) { 52 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 53 const content::LoadCommittedDetails load = 54 *content::Details<content::LoadCommittedDetails>(details).ptr(); 55 56 content::NavigationController* controller = 57 content::Source<content::NavigationController>(source).ptr(); 58 // Track whether the page loaded is a search results page (SRP). Track 59 // the non-SRP navigations as well so there is a control. 60 content::RecordAction(base::UserMetricsAction("NavEntryCommitted")); 61 // Attempting to determine the cause of a crash originating from 62 // IsSearchResultsPageFromDefaultSearchProvider but manifesting in 63 // TemplateURLRef::ExtractSearchTermsFromURL(...). 64 // See http://crbug.com/291348. 65 CHECK(load.entry); 66 if (TemplateURLServiceFactory::GetForProfile( 67 Profile::FromBrowserContext(controller->GetBrowserContext()))-> 68 IsSearchResultsPageFromDefaultSearchProvider( 69 load.entry->GetURL())) { 70 content::RecordAction(base::UserMetricsAction("NavEntryCommitted.SRP")); 71 } 72 73 if (!load.is_navigation_to_different_page()) 74 return; // Don't log for subframes or other trivial types. 75 76 LogRenderProcessHostCount(); 77 LogBrowserTabCount(); 78 } else if (type == chrome::NOTIFICATION_APP_TERMINATING) { 79 delete g_instance; 80 g_instance = NULL; 81 } 82 } 83 84 void UMABrowsingActivityObserver::LogRenderProcessHostCount() const { 85 int hosts_count = 0; 86 for (content::RenderProcessHost::iterator i( 87 content::RenderProcessHost::AllHostsIterator()); 88 !i.IsAtEnd(); i.Advance()) 89 ++hosts_count; 90 UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count, 91 1, 50, 50); 92 } 93 94 void UMABrowsingActivityObserver::LogBrowserTabCount() const { 95 int tab_count = 0; 96 int app_window_count = 0; 97 int popup_window_count = 0; 98 int tabbed_window_count = 0; 99 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 100 // Record how many tabs each window has open. 101 Browser* browser = *it; 102 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerWindow", 103 browser->tab_strip_model()->count(), 104 1, 200, 50); 105 tab_count += browser->tab_strip_model()->count(); 106 107 if (browser->window()->IsActive()) { 108 // Record how many tabs the active window has open. 109 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountActiveWindow", 110 browser->tab_strip_model()->count(), 111 1, 200, 50); 112 } 113 114 if (browser->is_app()) 115 app_window_count++; 116 else if (browser->is_type_popup()) 117 popup_window_count++; 118 else if (browser->is_type_tabbed()) 119 tabbed_window_count++; 120 } 121 // Record how many tabs total are open (across all windows). 122 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tab_count, 1, 200, 50); 123 124 // Record how many windows are open, by type. 125 UMA_HISTOGRAM_COUNTS_100("WindowManager.AppWindowCountPerLoad", 126 app_window_count); 127 UMA_HISTOGRAM_COUNTS_100("WindowManager.PopUpWindowCountPerLoad", 128 popup_window_count); 129 UMA_HISTOGRAM_COUNTS_100("WindowManager.TabbedWindowCountPerLoad", 130 tabbed_window_count); 131 } 132 133 } // namespace chrome 134