Home | History | Annotate | Download | only in webui
      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 
     27 MetricsHandler::MetricsHandler() {}
     28 MetricsHandler::~MetricsHandler() {}
     29 
     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 
     46 void MetricsHandler::HandleRecordAction(const base::ListValue* args) {
     47   std::string string_action = base::UTF16ToUTF8(ExtractStringValue(args));
     48   content::RecordComputedAction(string_action);
     49 }
     50 
     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 
     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 
    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