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 22using base::ListValue; 23using content::UserMetricsAction; 24using content::WebContents; 25 26MetricsHandler::MetricsHandler() {} 27MetricsHandler::~MetricsHandler() {} 28 29void 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 45void MetricsHandler::HandleRecordAction(const ListValue* args) { 46 std::string string_action = UTF16ToUTF8(ExtractStringValue(args)); 47 content::RecordComputedAction(string_action); 48} 49 50void 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 84void 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 117void 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