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