summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/uma_browsing_activity_observer.cc
blob: f0a53be62b88a3fa2f50413f4c8963f7c98088aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/uma_browsing_activity_observer.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/user_metrics.h"

namespace chrome {
namespace {

UMABrowsingActivityObserver* g_instance = NULL;

}  // namespace

// static
void UMABrowsingActivityObserver::Init() {
  DCHECK(!g_instance);
  // Must be created before any Browsers are.
  DCHECK_EQ(0U, chrome::GetTotalBrowserCount());
  g_instance = new UMABrowsingActivityObserver;
}

UMABrowsingActivityObserver::UMABrowsingActivityObserver() {
  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
                  content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
                  content::NotificationService::AllSources());
}

UMABrowsingActivityObserver::~UMABrowsingActivityObserver() {
}

void UMABrowsingActivityObserver::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
    const content::LoadCommittedDetails load =
        *content::Details<content::LoadCommittedDetails>(details).ptr();

    content::NavigationController* controller =
      content::Source<content::NavigationController>(source).ptr();
    // Track whether the page loaded is a search results page (SRP). Track
    // the non-SRP navigations as well so there is a control.
    content::RecordAction(content::UserMetricsAction("NavEntryCommitted"));
    // Attempting to determine the cause of a crash originating from
    // IsSearchResultsPageFromDefaultSearchProvider but manifesting in
    // TemplateURLRef::ExtractSearchTermsFromURL(...).
    // See http://crbug.com/291348.
    CHECK(load.entry);
    if (TemplateURLServiceFactory::GetForProfile(
            Profile::FromBrowserContext(controller->GetBrowserContext()))->
            IsSearchResultsPageFromDefaultSearchProvider(
                load.entry->GetURL())) {
      content::RecordAction(
          content::UserMetricsAction("NavEntryCommitted.SRP"));
    }

    if (!load.is_navigation_to_different_page())
      return;  // Don't log for subframes or other trivial types.

    LogRenderProcessHostCount();
    LogBrowserTabCount();
  } else if (type == chrome::NOTIFICATION_APP_TERMINATING) {
    delete g_instance;
    g_instance = NULL;
  }
}

void UMABrowsingActivityObserver::LogRenderProcessHostCount() const {
  int hosts_count = 0;
  for (content::RenderProcessHost::iterator i(
          content::RenderProcessHost::AllHostsIterator());
        !i.IsAtEnd(); i.Advance())
    ++hosts_count;
  UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count,
                              1, 50, 50);
}

void UMABrowsingActivityObserver::LogBrowserTabCount() const {
  int tab_count = 0;
  int app_window_count = 0;
  int popup_window_count = 0;
  int tabbed_window_count = 0;
  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
    // Record how many tabs each window has open.
    Browser* browser = *it;
    UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerWindow",
                                browser->tab_strip_model()->count(),
                                1, 200, 50);
    tab_count += browser->tab_strip_model()->count();

    if (browser->window()->IsActive()) {
      // Record how many tabs the active window has open.
      UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountActiveWindow",
                                  browser->tab_strip_model()->count(),
                                  1, 200, 50);
    }

    if (browser->is_app())
      app_window_count++;
    else if (browser->is_type_popup())
      popup_window_count++;
    else if (browser->is_type_tabbed())
      tabbed_window_count++;
  }
  // Record how many tabs total are open (across all windows).
  UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tab_count, 1, 200, 50);

  // Record how many windows are open, by type.
  UMA_HISTOGRAM_COUNTS_100("WindowManager.AppWindowCountPerLoad",
                           app_window_count);
  UMA_HISTOGRAM_COUNTS_100("WindowManager.PopUpWindowCountPerLoad",
                           popup_window_count);
  UMA_HISTOGRAM_COUNTS_100("WindowManager.TabbedWindowCountPerLoad",
                           tabbed_window_count);
}

}  // namespace chrome