14efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver// Copyright (c) 2012 The Chromium Authors. All rights reserved.
24efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver// Use of this source code is governed by a BSD-style license that can be
34efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver// found in the LICENSE file.
44efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
54efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/uma_browsing_activity_observer.h"
64efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
74efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "base/metrics/histogram.h"
84efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/chrome_notification_types.h"
94efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/search_engines/template_url_service_factory.h"
104efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/browser.h"
114efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/browser_finder.h"
124efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/browser_iterator.h"
134efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/browser_window.h"
144efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "chrome/browser/ui/tabs/tab_strip_model.h"
154efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "components/search_engines/template_url_service.h"
164efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "content/public/browser/navigation_controller.h"
174efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "content/public/browser/navigation_details.h"
184efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "content/public/browser/navigation_entry.h"
198be8df214189844d0782aba432b90d3706df8c4dBen Gruver#include "content/public/browser/notification_service.h"
208be8df214189844d0782aba432b90d3706df8c4dBen Gruver#include "content/public/browser/render_process_host.h"
214efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver#include "content/public/browser/user_metrics.h"
224efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
23b62237938eb1379980eb80004137d6dcd6ff14f7Ben Gruvernamespace chrome {
248be8df214189844d0782aba432b90d3706df8c4dBen Gruvernamespace {
254efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
264efe9403afb0ba3b83fa647eb82e4f90d29f131bBen GruverUMABrowsingActivityObserver* g_instance = NULL;
27a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver
28a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver}  // namespace
296f357d3284a833cc50a990e14b39f389b8972254Jeff Brown
30a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver// static
318be8df214189844d0782aba432b90d3706df8c4dBen Gruvervoid UMABrowsingActivityObserver::Init() {
32f157b48eae1469754d801e2bed5cdacd73e4399dBen Gruver  DCHECK(!g_instance);
334efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  // Must be created before any Browsers are.
344efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  DCHECK_EQ(0U, chrome::GetTotalBrowserCount());
35f157b48eae1469754d801e2bed5cdacd73e4399dBen Gruver  g_instance = new UMABrowsingActivityObserver;
364efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver}
378be8df214189844d0782aba432b90d3706df8c4dBen Gruver
384efe9403afb0ba3b83fa647eb82e4f90d29f131bBen GruverUMABrowsingActivityObserver::UMABrowsingActivityObserver() {
394efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
404efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                  content::NotificationService::AllSources());
414efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
424efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                  content::NotificationService::AllSources());
434efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver}
444efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
454efe9403afb0ba3b83fa647eb82e4f90d29f131bBen GruverUMABrowsingActivityObserver::~UMABrowsingActivityObserver() {
464efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver}
47f157b48eae1469754d801e2bed5cdacd73e4399dBen Gruver
484efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruvervoid UMABrowsingActivityObserver::Observe(
494efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    int type,
504efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    const content::NotificationSource& source,
514efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    const content::NotificationDetails& details) {
52dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver  if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
534efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    const content::LoadCommittedDetails load =
54b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver        *content::Details<content::LoadCommittedDetails>(details).ptr();
55b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver
564efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    content::NavigationController* controller =
578be8df214189844d0782aba432b90d3706df8c4dBen Gruver      content::Source<content::NavigationController>(source).ptr();
588be8df214189844d0782aba432b90d3706df8c4dBen Gruver    // Track whether the page loaded is a search results page (SRP). Track
598be8df214189844d0782aba432b90d3706df8c4dBen Gruver    // the non-SRP navigations as well so there is a control.
604efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    content::RecordAction(base::UserMetricsAction("NavEntryCommitted"));
614efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    // Attempting to determine the cause of a crash originating from
624efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    // IsSearchResultsPageFromDefaultSearchProvider but manifesting in
634efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    // TemplateURLRef::ExtractSearchTermsFromURL(...).
644efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    // See http://crbug.com/291348.
658be8df214189844d0782aba432b90d3706df8c4dBen Gruver    CHECK(load.entry);
66a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    if (TemplateURLServiceFactory::GetForProfile(
67a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver            Profile::FromBrowserContext(controller->GetBrowserContext()))->
688be8df214189844d0782aba432b90d3706df8c4dBen Gruver            IsSearchResultsPageFromDefaultSearchProvider(
694efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                load.entry->GetURL())) {
704efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver      content::RecordAction(base::UserMetricsAction("NavEntryCommitted.SRP"));
714efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    }
724efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
73a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    if (!load.is_navigation_to_different_page())
74a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver      return;  // Don't log for subframes or other trivial types.
75a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver
76a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    LogRenderProcessHostCount();
77a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    LogBrowserTabCount();
784efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  } else if (type == chrome::NOTIFICATION_APP_TERMINATING) {
794efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    delete g_instance;
804efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    g_instance = NULL;
814efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  }
824efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver}
834efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
844efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruvervoid UMABrowsingActivityObserver::LogRenderProcessHostCount() const {
854efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  int hosts_count = 0;
864efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  for (content::RenderProcessHost::iterator i(
874efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver          content::RenderProcessHost::AllHostsIterator());
884efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver        !i.IsAtEnd(); i.Advance())
894efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    ++hosts_count;
904efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count,
914efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                              1, 50, 50);
9257e76b405faf154352e17f0114bf6b23aa9ac0f0Ben Gruver}
934efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
944efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruvervoid UMABrowsingActivityObserver::LogBrowserTabCount() const {
954efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  int tab_count = 0;
964efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  int app_window_count = 0;
974efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  int popup_window_count = 0;
98b2340f3fcc2cfded97e0372a336bcf6f9211e0c1Ben Gruver  int tabbed_window_count = 0;
994efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1004efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    // Record how many tabs each window has open.
1014efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    Browser* browser = *it;
1024efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerWindow",
1034efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                                browser->tab_strip_model()->count(),
1044efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                                1, 200, 50);
1054efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    tab_count += browser->tab_strip_model()->count();
1064efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver
1074efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    if (browser->window()->IsActive()) {
1084efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver      // Record how many tabs the active window has open.
1094efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver      UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountActiveWindow",
1104efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                                  browser->tab_strip_model()->count(),
1116f357d3284a833cc50a990e14b39f389b8972254Jeff Brown                                  1, 200, 50);
1124efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    }
1136f357d3284a833cc50a990e14b39f389b8972254Jeff Brown
114b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver    if (browser->is_app())
115b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver      app_window_count++;
116a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    else if (browser->is_type_popup())
117b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver      popup_window_count++;
118a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver    else if (browser->is_type_tabbed())
119b7c1a17846a306deef62855630bca9f061dc9372Ben Gruver      tabbed_window_count++;
120a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver  }
1214efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  // Record how many tabs total are open (across all windows).
1224efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver  UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tab_count, 1, 200, 50);
123a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver
124a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver  // Record how many windows are open, by type.
125a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver  UMA_HISTOGRAM_COUNTS_100("WindowManager.AppWindowCountPerLoad",
126a4879c3425ae6ce46d7e7273c081a973a1c79ac6Ben Gruver                           app_window_count);
127dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver  UMA_HISTOGRAM_COUNTS_100("WindowManager.PopUpWindowCountPerLoad",
128b62237938eb1379980eb80004137d6dcd6ff14f7Ben Gruver                           popup_window_count);
129f5323fee2a7deaf264ed10fbe3d9c69055987e55Ben Gruver  UMA_HISTOGRAM_COUNTS_100("WindowManager.TabbedWindowCountPerLoad",
13049660c7c24f24c3394233e3bbf94c96281e8c408Ben Gruver                           tabbed_window_count);
131b62237938eb1379980eb80004137d6dcd6ff14f7Ben Gruver}
132b62237938eb1379980eb80004137d6dcd6ff14f7Ben Gruver
133f5323fee2a7deaf264ed10fbe3d9c69055987e55Ben Gruver}  // namespace chrome
134f5323fee2a7deaf264ed10fbe3d9c69055987e55Ben Gruver