15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/external_metrics.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/files/file_path.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/field_trial.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/metrics/sparse_histogram.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/timer/elapsed_timer.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/chromeos_metrics_provider.h" 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/metrics_service.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/metrics/serialization/metric_sample.h" 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/metrics/serialization/serialization_utils.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckValues(const std::string& name, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int minimum, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maximum, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bucket_count) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Histogram::InspectConstructionArguments( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, &minimum, &maximum, &bucket_count)) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::HistogramBase* histogram = 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StatisticsRecorder::FindHistogram(name); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!histogram) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return histogram->HasConstructionArguments(minimum, maximum, bucket_count); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckLinearValues(const std::string& name, int maximum) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CheckValues(name, 1, maximum, maximum + 1); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Establishes field trial for wifi scanning in chromeos. crbug.com/242733. 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SetupProgressiveScanFieldTrial() { 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char name_of_experiment[] = "ProgressiveScan"; 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::FilePath group_file_path( 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "/home/chronos/.progressive_scan_variation"); 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FieldTrial::Probability kDivisor = 1000; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<base::FieldTrial> trial = 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::FieldTrialList::FactoryGetFieldTrial( 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch name_of_experiment, kDivisor, "Default", 2013, 12, 31, 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::FieldTrial::SESSION_RANDOMIZED, NULL); 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Announce the groups with 0 percentage; the actual percentages come from 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the server configuration. 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::map<int, std::string> group_to_char; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_to_char[trial->AppendGroup("FullScan", 0)] = "c"; 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_to_char[trial->AppendGroup("33Percent_4MinMax", 0)] = "1"; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_to_char[trial->AppendGroup("50Percent_4MinMax", 0)] = "2"; 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_to_char[trial->AppendGroup("50Percent_8MinMax", 0)] = "3"; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_to_char[trial->AppendGroup("100Percent_8MinMax", 0)] = "4"; 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) group_to_char[trial->AppendGroup("100Percent_1MinSeen_A", 0)] = "5"; 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) group_to_char[trial->AppendGroup("100Percent_1MinSeen_B", 0)] = "6"; 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) group_to_char[trial->AppendGroup("100Percent_1Min_4Max", 0)] = "7"; 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Announce the experiment to any listeners (especially important is the UMA 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // software, which will append the group names to UMA statistics). 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int group_num = trial->group(); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string group_char = "x"; 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ContainsKey(group_to_char, group_num)) 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch group_char = group_to_char[group_num]; 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write the group to the file to be read by ChromeOS. 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int size = static_cast<int>(group_char.length()); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (base::WriteFile(group_file_path, group_char.c_str(), size) == size) { 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "Configured in group '" << trial->group_name() 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << "' ('" << group_char << "') for " 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << name_of_experiment << " field trial"; 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "Couldn't write to " << group_file_path.value(); 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The interval between external metrics collections in seconds 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kExternalMetricsCollectionIntervalSeconds = 30; 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kEventsFilePath[] = "/var/run/metrics/uma-events"; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) { 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExternalMetrics::~ExternalMetrics() {} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::Start() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register user actions external to the browser. 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // tools/metrics/actions/extract_actions.py won't understand these lines, so 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // all of these are explicitly added in that script. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(derat): We shouldn't need to verify actions before reporting them; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove all of this once http://crosbug.com/11125 is fixed. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_user_actions_.insert("Cryptohome.PKCS11InitFail"); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_user_actions_.insert("Updater.ServerCertificateChanged"); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_user_actions_.insert("Updater.ServerCertificateFailed"); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Initialize here field trials that don't need to read from files. 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // (None for the moment.) 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Initialize any chromeos field trials that need to read from a file (e.g., 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // those that have an upstart script determine their experimental group for 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // them) then schedule the data collection. All of this is done on the file 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // thread. 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool task_posted = BrowserThread::PostTask( 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserThread::FILE, 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&chromeos::ExternalMetrics::SetupFieldTrialsOnFileThread, 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this)); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(task_posted); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting( 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& filename) { 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics()); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) external_metrics->uma_events_file_ = filename; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return external_metrics; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::RecordActionUI(std::string action_string) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (valid_user_actions_.count(action_string)) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordComputedAction(action_string); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DLOG(ERROR) << "undefined UMA action: " << action_string; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExternalMetrics::RecordAction(const std::string& action) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrowserThread::UI, 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ExternalMetrics::RecordActionUI, this, action)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) { 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ChromeOSMetricsProvider::LogCrash(crash_kind); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::RecordCrash(const std::string& crash_kind) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) { 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type()); 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!CheckValues( 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.name(), sample.min(), sample.max(), sample.bucket_count())) { 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DLOG(ERROR) << "Invalid histogram: " << sample.name(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::HistogramBase* counter = 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Histogram::FactoryGet(sample.name(), 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.min(), 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.max(), 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.bucket_count(), 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Histogram::kUmaTargetedHistogramFlag); 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) counter->Add(sample.sample()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExternalMetrics::RecordLinearHistogram( 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const metrics::MetricSample& sample) { 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type()); 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!CheckLinearValues(sample.name(), sample.max())) { 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DLOG(ERROR) << "Invalid linear histogram: " << sample.name(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.name(), 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1, 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.max(), 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.max() + 1, 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Histogram::kUmaTargetedHistogramFlag); 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) counter->Add(sample.sample()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExternalMetrics::RecordSparseHistogram( 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const metrics::MetricSample& sample) { 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type()); 198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::HistogramBase* counter = base::SparseHistogram::FactoryGet( 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag); 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) counter->Add(sample.sample()); 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ExternalMetrics::CollectEvents() { 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedVector<metrics::MetricSample> samples; 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_, 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &samples); 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (ScopedVector<metrics::MetricSample>::iterator it = samples.begin(); 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != samples.end(); 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const metrics::MetricSample& sample = **it; 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // instance and thus only work if |sample.name()| is constant. 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (sample.type()) { 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case metrics::MetricSample::CRASH: 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordCrash(sample.name()); 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case metrics::MetricSample::USER_ACTION: 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordAction(sample.name()); 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case metrics::MetricSample::HISTOGRAM: 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordHistogram(sample); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case metrics::MetricSample::LINEAR_HISTOGRAM: 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordLinearHistogram(sample); 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case metrics::MetricSample::SPARSE_HISTOGRAM: 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordSparseHistogram(sample); 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return samples.size(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::CollectEventsAndReschedule() { 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ElapsedTimer timer; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollectEvents(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCollector(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalMetrics::ScheduleCollector() { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = BrowserThread::PostDelayedTask( 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) BrowserThread::FILE, FROM_HERE, 248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule, this), 249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ExternalMetrics::SetupFieldTrialsOnFileThread() { 254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Field trials that do not read from files can be initialized in 256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ExternalMetrics::Start() above. 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetupProgressiveScanFieldTrial(); 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScheduleCollector(); 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 263