• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/webui/metrics_handler.h"
6 
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/metrics/metric_event_duration_details.h"
15 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
16 #include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
17 #include "chrome/common/ntp_logging_events.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_ui.h"
22 
23 using base::ListValue;
24 using base::UserMetricsAction;
25 using content::WebContents;
26 
MetricsHandler()27 MetricsHandler::MetricsHandler() {}
~MetricsHandler()28 MetricsHandler::~MetricsHandler() {}
29 
RegisterMessages()30 void MetricsHandler::RegisterMessages() {
31   web_ui()->RegisterMessageCallback(
32       "metricsHandler:recordAction",
33       base::Bind(&MetricsHandler::HandleRecordAction, base::Unretained(this)));
34   web_ui()->RegisterMessageCallback(
35       "metricsHandler:recordInHistogram",
36       base::Bind(&MetricsHandler::HandleRecordInHistogram,
37                  base::Unretained(this)));
38   web_ui()->RegisterMessageCallback(
39       "metricsHandler:logEventTime",
40       base::Bind(&MetricsHandler::HandleLogEventTime, base::Unretained(this)));
41   web_ui()->RegisterMessageCallback(
42       "metricsHandler:logMouseover",
43       base::Bind(&MetricsHandler::HandleLogMouseover, base::Unretained(this)));
44 }
45 
HandleRecordAction(const base::ListValue * args)46 void MetricsHandler::HandleRecordAction(const base::ListValue* args) {
47   std::string string_action = base::UTF16ToUTF8(ExtractStringValue(args));
48   content::RecordComputedAction(string_action);
49 }
50 
HandleRecordInHistogram(const base::ListValue * args)51 void MetricsHandler::HandleRecordInHistogram(const base::ListValue* args) {
52   std::string histogram_name;
53   double value;
54   double boundary_value;
55   if (!args->GetString(0, &histogram_name) ||
56       !args->GetDouble(1, &value) ||
57       !args->GetDouble(2, &boundary_value)) {
58     NOTREACHED();
59     return;
60   }
61 
62   int int_value = static_cast<int>(value);
63   int int_boundary_value = static_cast<int>(boundary_value);
64   if (int_boundary_value >= 4000 ||
65       int_value > int_boundary_value ||
66       int_value < 0) {
67     NOTREACHED();
68     return;
69   }
70 
71   int bucket_count = int_boundary_value;
72   while (bucket_count >= 100) {
73     bucket_count /= 10;
74   }
75 
76   // As |histogram_name| may change between calls, the UMA_HISTOGRAM_ENUMERATION
77   // macro cannot be used here.
78   base::HistogramBase* counter =
79       base::LinearHistogram::FactoryGet(
80           histogram_name, 1, int_boundary_value, bucket_count + 1,
81           base::HistogramBase::kUmaTargetedHistogramFlag);
82   counter->Add(int_value);
83 }
84 
HandleLogEventTime(const base::ListValue * args)85 void MetricsHandler::HandleLogEventTime(const base::ListValue* args) {
86   std::string event_name = base::UTF16ToUTF8(ExtractStringValue(args));
87   WebContents* tab = web_ui()->GetWebContents();
88 
89   // Not all new tab pages get timed. In those cases, we don't have a
90   // new_tab_start_time_.
91   CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(tab);
92   if (core_tab_helper->new_tab_start_time().is_null())
93     return;
94 
95   base::TimeDelta duration =
96       base::TimeTicks::Now() - core_tab_helper->new_tab_start_time();
97   MetricEventDurationDetails details(event_name,
98       static_cast<int>(duration.InMilliseconds()));
99 
100   if (event_name == "Tab.NewTabScriptStart") {
101     UMA_HISTOGRAM_TIMES("Tab.NewTabScriptStart", duration);
102   } else if (event_name == "Tab.NewTabDOMContentLoaded") {
103     UMA_HISTOGRAM_TIMES("Tab.NewTabDOMContentLoaded", duration);
104   } else if (event_name == "Tab.NewTabOnload") {
105     UMA_HISTOGRAM_TIMES("Tab.NewTabOnload", duration);
106     // The new tab page has finished loading; reset it.
107     CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(tab);
108     core_tab_helper->set_new_tab_start_time(base::TimeTicks());
109   } else {
110     NOTREACHED();
111   }
112   content::NotificationService::current()->Notify(
113       chrome::NOTIFICATION_METRIC_EVENT_DURATION,
114       content::Source<WebContents>(tab),
115       content::Details<MetricEventDurationDetails>(&details));
116 }
117 
HandleLogMouseover(const base::ListValue * args)118 void MetricsHandler::HandleLogMouseover(const base::ListValue* args) {
119 #if !defined(OS_ANDROID)
120   // Android uses native UI for NTP.
121   NTPUserDataLogger::GetOrCreateFromWebContents(
122       web_ui()->GetWebContents())->LogEvent(NTP_MOUSEOVER);
123 #endif  // !defined(OS_ANDROID)
124 }
125