blob: 5d0f07bea84ec93d19d7344d159a4ca6cdc33ac2 [file] [log] [blame]
Thieu Lead1ec2c2012-01-05 23:39:48 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Thieu Le48e6d6d2011-12-06 00:40:27 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/metrics.h"
6
Ben Chana0ddf462014-02-06 11:32:42 -08007#include <base/strings/string_util.h>
8#include <base/strings/stringprintf.h>
Thieu Lead1ec2c2012-01-05 23:39:48 +00009#include <chromeos/dbus/service_constants.h>
Darin Petkov58f0b6d2012-06-12 12:52:30 +020010#include <metrics/bootstat.h>
Thieu Le48e6d6d2011-12-06 00:40:27 +000011
Wade Guthried4977f22012-08-22 12:37:54 -070012#include "shill/ieee80211.h"
Paul Stewartff845fc2012-08-07 07:28:44 -070013#include "shill/link_monitor.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070014#include "shill/logging.h"
Thieu Le48e6d6d2011-12-06 00:40:27 +000015#include "shill/wifi_service.h"
16
17using std::string;
Alex Vakulenko8a532292014-06-16 17:18:44 -070018using std::shared_ptr;
Thieu Le48e6d6d2011-12-06 00:40:27 +000019
20namespace shill {
21
mukesh agrawal132e96f2014-04-24 11:49:42 -070022static const char kMetricPrefix[] = "Network.Shill";
23
Thieu Le48e6d6d2011-12-06 00:40:27 +000024// static
Thieu Lec31e6f92012-08-03 13:08:58 -070025// Our disconnect enumeration values are 0 (System Disconnect) and
26// 1 (User Disconnect), see histograms.xml, but Chrome needs a minimum
27// enum value of 1 and the minimum number of buckets needs to be 3 (see
28// histogram.h). Instead of remapping System Disconnect to 1 and
29// User Disconnect to 2, we can just leave the enumerated values as-is
30// because Chrome implicitly creates a [0-1) bucket for us. Using Min=1,
31// Max=2 and NumBuckets=3 gives us the following three buckets:
32// [0-1), [1-2), [2-INT_MAX). We end up with an extra bucket [2-INT_MAX)
33// that we can safely ignore.
mukesh agrawal132e96f2014-04-24 11:49:42 -070034const char Metrics::kMetricDisconnectSuffix[] = "Disconnect";
Thieu Lec31e6f92012-08-03 13:08:58 -070035const int Metrics::kMetricDisconnectMax = 2;
36const int Metrics::kMetricDisconnectMin = 1;
37const int Metrics::kMetricDisconnectNumBuckets = 3;
Thieu Le67370f62012-02-14 23:01:42 +000038
mukesh agrawal132e96f2014-04-24 11:49:42 -070039const char Metrics::kMetricSignalAtDisconnectSuffix[] = "SignalAtDisconnect";
Wade Guthrie9ec08062013-09-25 15:22:24 -070040const int Metrics::kMetricSignalAtDisconnectMin = 0;
41const int Metrics::kMetricSignalAtDisconnectMax = 200;
42const int Metrics::kMetricSignalAtDisconnectNumBuckets = 40;
43
mukesh agrawal132e96f2014-04-24 11:49:42 -070044const char Metrics::kMetricNetworkApModeSuffix[] = "ApMode";
45const char Metrics::kMetricNetworkChannelSuffix[] = "Channel";
Thieu Le48e6d6d2011-12-06 00:40:27 +000046const int Metrics::kMetricNetworkChannelMax = Metrics::kWiFiChannelMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070047const char Metrics::kMetricNetworkEapInnerProtocolSuffix[] = "EapInnerProtocol";
Paul Stewart21f40962013-03-01 14:27:28 -080048const int Metrics::kMetricNetworkEapInnerProtocolMax =
49 Metrics::kEapInnerProtocolMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070050const char Metrics::kMetricNetworkEapOuterProtocolSuffix[] = "EapOuterProtocol";
Paul Stewart21f40962013-03-01 14:27:28 -080051const int Metrics::kMetricNetworkEapOuterProtocolMax =
52 Metrics::kEapOuterProtocolMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070053const char Metrics::kMetricNetworkPhyModeSuffix[] = "PhyMode";
Thieu Lead1ec2c2012-01-05 23:39:48 +000054const int Metrics::kMetricNetworkPhyModeMax = Metrics::kWiFiNetworkPhyModeMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070055const char Metrics::kMetricNetworkSecuritySuffix[] = "Security";
Thieu Lead1ec2c2012-01-05 23:39:48 +000056const int Metrics::kMetricNetworkSecurityMax = Metrics::kWiFiSecurityMax;
Thieu Le48e6d6d2011-12-06 00:40:27 +000057const char Metrics::kMetricNetworkServiceErrors[] =
58 "Network.Shill.ServiceErrors";
59const int Metrics::kMetricNetworkServiceErrorsMax = Service::kFailureMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070060const char Metrics::kMetricNetworkSignalStrengthSuffix[] = "SignalStrength";
Paul Stewart23b393a2012-09-25 21:21:06 -070061const int Metrics::kMetricNetworkSignalStrengthMax = 200;
62const int Metrics::kMetricNetworkSignalStrengthMin = 0;
63const int Metrics::kMetricNetworkSignalStrengthNumBuckets = 40;
Thieu Lea20cbc22012-01-09 22:01:43 +000064
Paul Stewart4ef524d2014-07-23 13:11:29 -070065const char Metrics::kMetricRememberedWiFiNetworkCount[] =
66 "Network.Shill.WiFi.RememberedNetworkCount";
67const int Metrics::kMetricRememberedWiFiNetworkCountMax = 1024;
68const int Metrics::kMetricRememberedWiFiNetworkCountMin = 0;
69const int Metrics::kMetricRememberedWiFiNetworkCountNumBuckets = 32;
70
mukesh agrawal132e96f2014-04-24 11:49:42 -070071const char Metrics::kMetricTimeOnlineSecondsSuffix[] = "TimeOnline";
Thieu Lea20cbc22012-01-09 22:01:43 +000072const int Metrics::kMetricTimeOnlineSecondsMax = 8 * 60 * 60; // 8 hours
73const int Metrics::kMetricTimeOnlineSecondsMin = 1;
74
mukesh agrawal132e96f2014-04-24 11:49:42 -070075const char Metrics::kMetricTimeToConnectMillisecondsSuffix[] = "TimeToConnect";
Thieu Lecdb5a212013-01-25 11:17:18 -080076const int Metrics::kMetricTimeToConnectMillisecondsMax =
77 60 * 1000; // 60 seconds
78const int Metrics::kMetricTimeToConnectMillisecondsMin = 1;
79const int Metrics::kMetricTimeToConnectMillisecondsNumBuckets = 60;
80
mukesh agrawal132e96f2014-04-24 11:49:42 -070081const char Metrics::kMetricTimeToScanAndConnectMillisecondsSuffix[] =
82 "TimeToScanAndConnect";
Wade Guthrie44f290d2013-05-28 10:16:25 -070083
Thieu Lea20cbc22012-01-09 22:01:43 +000084const char Metrics::kMetricTimeToDropSeconds[] = "Network.Shill.TimeToDrop";;
85const int Metrics::kMetricTimeToDropSecondsMax = 8 * 60 * 60; // 8 hours
86const int Metrics::kMetricTimeToDropSecondsMin = 1;
87
mukesh agrawal132e96f2014-04-24 11:49:42 -070088const char Metrics::kMetricTimeToDisableMillisecondsSuffix[] = "TimeToDisable";
Thieu Lea2519bf2013-01-23 16:51:54 -080089const int Metrics::kMetricTimeToDisableMillisecondsMax =
90 60 * 1000; // 60 seconds
91const int Metrics::kMetricTimeToDisableMillisecondsMin = 1;
92const int Metrics::kMetricTimeToDisableMillisecondsNumBuckets = 60;
93
mukesh agrawal132e96f2014-04-24 11:49:42 -070094const char Metrics::kMetricTimeToEnableMillisecondsSuffix[] = "TimeToEnable";
Thieu Lece4483e2013-01-23 15:12:03 -080095const int Metrics::kMetricTimeToEnableMillisecondsMax =
96 60 * 1000; // 60 seconds
97const int Metrics::kMetricTimeToEnableMillisecondsMin = 1;
98const int Metrics::kMetricTimeToEnableMillisecondsNumBuckets = 60;
99
mukesh agrawal132e96f2014-04-24 11:49:42 -0700100const char Metrics::kMetricTimeToInitializeMillisecondsSuffix[] =
101 "TimeToInitialize";
Thieu Le769d50d2013-01-23 17:11:59 -0800102const int Metrics::kMetricTimeToInitializeMillisecondsMax =
103 30 * 1000; // 30 seconds
Thieu Lece4483e2013-01-23 15:12:03 -0800104const int Metrics::kMetricTimeToInitializeMillisecondsMin = 1;
Thieu Le769d50d2013-01-23 17:11:59 -0800105const int Metrics::kMetricTimeToInitializeMillisecondsNumBuckets = 30;
Thieu Lec8078a62013-01-22 18:01:12 -0800106
mukesh agrawal132e96f2014-04-24 11:49:42 -0700107const char Metrics::kMetricTimeResumeToReadyMillisecondsSuffix[] =
108 "TimeResumeToReady";
109const char Metrics::kMetricTimeToConfigMillisecondsSuffix[] = "TimeToConfig";
110const char Metrics::kMetricTimeToJoinMillisecondsSuffix[] = "TimeToJoin";
111const char Metrics::kMetricTimeToOnlineMillisecondsSuffix[] = "TimeToOnline";
112const char Metrics::kMetricTimeToPortalMillisecondsSuffix[] = "TimeToPortal";
Thieu Le18c11072013-01-28 17:21:37 -0800113
mukesh agrawal132e96f2014-04-24 11:49:42 -0700114const char Metrics::kMetricTimeToScanMillisecondsSuffix[] = "TimeToScan";
Thieu Le18c11072013-01-28 17:21:37 -0800115const int Metrics::kMetricTimeToScanMillisecondsMax = 180 * 1000; // 3 minutes
116const int Metrics::kMetricTimeToScanMillisecondsMin = 1;
117const int Metrics::kMetricTimeToScanMillisecondsNumBuckets = 90;
118
Thieu Lea20cbc22012-01-09 22:01:43 +0000119const int Metrics::kTimerHistogramMillisecondsMax = 45 * 1000;
120const int Metrics::kTimerHistogramMillisecondsMin = 1;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000121const int Metrics::kTimerHistogramNumBuckets = 50;
122
mukesh agrawal132e96f2014-04-24 11:49:42 -0700123const char Metrics::kMetricPortalAttemptsSuffix[] = "PortalAttempts";
Thieu Le85e050b2012-03-13 15:04:38 -0700124const int Metrics::kMetricPortalAttemptsMax =
125 PortalDetector::kMaxRequestAttempts;
126const int Metrics::kMetricPortalAttemptsMin = 1;
127const int Metrics::kMetricPortalAttemptsNumBuckets =
128 Metrics::kMetricPortalAttemptsMax;
129
mukesh agrawal132e96f2014-04-24 11:49:42 -0700130const char Metrics::kMetricPortalAttemptsToOnlineSuffix[] =
131 "PortalAttemptsToOnline";
Thieu Le85e050b2012-03-13 15:04:38 -0700132const int Metrics::kMetricPortalAttemptsToOnlineMax = 100;
133const int Metrics::kMetricPortalAttemptsToOnlineMin = 1;
134const int Metrics::kMetricPortalAttemptsToOnlineNumBuckets = 10;
135
mukesh agrawal132e96f2014-04-24 11:49:42 -0700136const char Metrics::kMetricPortalResultSuffix[] = "PortalResult";
Thieu Le85e050b2012-03-13 15:04:38 -0700137
Wade Guthrie60a37062013-04-02 11:39:09 -0700138const char Metrics::kMetricFrequenciesConnectedEver[] =
139 "Network.Shill.WiFi.FrequenciesConnectedEver";
140const int Metrics::kMetricFrequenciesConnectedMax = 50;
141const int Metrics::kMetricFrequenciesConnectedMin = 1;
142const int Metrics::kMetricFrequenciesConnectedNumBuckets = 50;
143
Wade Guthrieb9e0ee72013-05-31 09:23:30 -0700144const char Metrics::kMetricScanResult[] =
145 "Network.Shill.WiFi.ScanResult";
Wade Guthrief22681f2013-05-31 11:46:31 -0700146const char Metrics::kMetricWiFiScanTimeInEbusyMilliseconds[] =
147 "Network.Shill.WiFi.ScanTimeInEbusy";
148
Arman Ugurayab22c162012-10-08 19:08:38 -0700149const char Metrics::kMetricTerminationActionTimeOnTerminate[] =
150 "Network.Shill.TerminationActionTime.OnTerminate";
151const char Metrics::kMetricTerminationActionResultOnTerminate[] =
152 "Network.Shill.TerminationActionResult.OnTerminate";
153const char Metrics::kMetricTerminationActionTimeOnSuspend[] =
154 "Network.Shill.TerminationActionTime.OnSuspend";
155const char Metrics::kMetricTerminationActionResultOnSuspend[] =
156 "Network.Shill.TerminationActionResult.OnSuspend";
157const int Metrics::kMetricTerminationActionTimeMillisecondsMax = 10000;
158const int Metrics::kMetricTerminationActionTimeMillisecondsMin = 1;
Arman Uguray6d528f12012-09-13 13:44:55 -0700159
Thieu Le48e6d6d2011-12-06 00:40:27 +0000160// static
mukesh agrawal132e96f2014-04-24 11:49:42 -0700161const char Metrics::kMetricServiceFixupEntriesSuffix[] = "ServiceFixupEntries";
Paul Stewart85aea152013-01-22 09:31:56 -0800162
163// static
Ben Chan7fab8972014-08-10 17:14:46 -0700164const uint16_t Metrics::kWiFiBandwidth5MHz = 5;
165const uint16_t Metrics::kWiFiBandwidth20MHz = 20;
166const uint16_t Metrics::kWiFiFrequency2412 = 2412;
167const uint16_t Metrics::kWiFiFrequency2472 = 2472;
168const uint16_t Metrics::kWiFiFrequency2484 = 2484;
169const uint16_t Metrics::kWiFiFrequency5170 = 5170;
170const uint16_t Metrics::kWiFiFrequency5180 = 5180;
171const uint16_t Metrics::kWiFiFrequency5230 = 5230;
172const uint16_t Metrics::kWiFiFrequency5240 = 5240;
173const uint16_t Metrics::kWiFiFrequency5320 = 5320;
174const uint16_t Metrics::kWiFiFrequency5500 = 5500;
175const uint16_t Metrics::kWiFiFrequency5700 = 5700;
176const uint16_t Metrics::kWiFiFrequency5745 = 5745;
177const uint16_t Metrics::kWiFiFrequency5825 = 5825;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000178
Thieu Leb84ba342012-03-02 15:15:19 -0800179// static
180const char Metrics::kMetricPowerManagerKey[] = "metrics";
181
Paul Stewartff845fc2012-08-07 07:28:44 -0700182// static
mukesh agrawal132e96f2014-04-24 11:49:42 -0700183const char Metrics::kMetricLinkMonitorFailureSuffix[] = "LinkMonitorFailure";
184const char Metrics::kMetricLinkMonitorResponseTimeSampleSuffix[] =
185 "LinkMonitorResponseTimeSample";
Paul Stewartf1961f82012-09-11 20:45:39 -0700186const int Metrics::kMetricLinkMonitorResponseTimeSampleMin = 0;
187const int Metrics::kMetricLinkMonitorResponseTimeSampleMax =
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700188 LinkMonitor::kDefaultTestPeriodMilliseconds;
Paul Stewartff845fc2012-08-07 07:28:44 -0700189const int Metrics::kMetricLinkMonitorResponseTimeSampleNumBuckets = 50;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700190const char Metrics::kMetricLinkMonitorSecondsToFailureSuffix[] =
191 "LinkMonitorSecondsToFailure";
Paul Stewartf1961f82012-09-11 20:45:39 -0700192const int Metrics::kMetricLinkMonitorSecondsToFailureMin = 0;
193const int Metrics::kMetricLinkMonitorSecondsToFailureMax = 7200;
Paul Stewart0443aa52012-08-09 10:43:50 -0700194const int Metrics::kMetricLinkMonitorSecondsToFailureNumBuckets = 50;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700195const char Metrics::kMetricLinkMonitorBroadcastErrorsAtFailureSuffix[] =
196 "LinkMonitorBroadcastErrorsAtFailure";
197const char Metrics::kMetricLinkMonitorUnicastErrorsAtFailureSuffix[] =
198 "LinkMonitorUnicastErrorsAtFailure";
Paul Stewartf1961f82012-09-11 20:45:39 -0700199const int Metrics::kMetricLinkMonitorErrorCountMin = 0;
200const int Metrics::kMetricLinkMonitorErrorCountMax =
Paul Stewart0443aa52012-08-09 10:43:50 -0700201 LinkMonitor::kFailureThreshold;
202const int Metrics::kMetricLinkMonitorErrorCountNumBuckets =
203 LinkMonitor::kFailureThreshold + 1;
Paul Stewartff845fc2012-08-07 07:28:44 -0700204
Wade Guthried4977f22012-08-22 12:37:54 -0700205// static
206const char Metrics::kMetricLinkClientDisconnectReason[] =
207 "Network.Shill.WiFi.ClientDisconnectReason";
208const char Metrics::kMetricLinkApDisconnectReason[] =
209 "Network.Shill.WiFi.ApDisconnectReason";
210const char Metrics::kMetricLinkClientDisconnectType[] =
211 "Network.Shill.WiFi.ClientDisconnectType";
212const char Metrics::kMetricLinkApDisconnectType[] =
213 "Network.Shill.WiFi.ApDisconnectType";
214
Thieu Le26fc01b2013-01-28 12:08:48 -0800215// static
Prathmesh Prabhu08757aa2013-05-15 17:17:33 -0700216const char Metrics::kMetricCellular3GPPRegistrationDelayedDrop[] =
217 "Network.Shill.Cellular.3GPPRegistrationDelayedDrop";
Thieu Le91fccf62013-04-22 15:23:16 -0700218const char Metrics::kMetricCellularAutoConnectTries[] =
219 "Network.Shill.Cellular.AutoConnectTries";
220const int Metrics::kMetricCellularAutoConnectTriesMax = 20;
221const int Metrics::kMetricCellularAutoConnectTriesMin = 1;
222const int Metrics::kMetricCellularAutoConnectTriesNumBuckets = 20;
223const char Metrics::kMetricCellularAutoConnectTotalTime[] =
224 "Network.Shill.Cellular.AutoConnectTotalTime";
225const int Metrics::kMetricCellularAutoConnectTotalTimeMax =
226 60 * 1000; // 60 seconds
227const int Metrics::kMetricCellularAutoConnectTotalTimeMin = 0;
228const int Metrics::kMetricCellularAutoConnectTotalTimeNumBuckets = 60;
Thieu Le26fc01b2013-01-28 12:08:48 -0800229const char Metrics::kMetricCellularDrop[] =
230 "Network.Shill.Cellular.Drop";
Thieu Leb7aa5f72013-01-31 15:57:48 -0800231// The format of FailureReason is different to other metrics because this
232// name is prepended to the error message before the entire string is sent
233// via SendUserActionToUMA.
234const char Metrics::kMetricCellularFailureReason[] =
235 "Network.Shill.Cellular.FailureReason: ";
Thieu Le91fccf62013-04-22 15:23:16 -0700236const char Metrics::kMetricCellularOutOfCreditsReason[] =
237 "Network.Shill.Cellular.OutOfCreditsReason";
Thieu Le26fc01b2013-01-28 12:08:48 -0800238const char Metrics::kMetricCellularSignalStrengthBeforeDrop[] =
239 "Network.Shill.Cellular.SignalStrengthBeforeDrop";
240const int Metrics::kMetricCellularSignalStrengthBeforeDropMax = 100;
241const int Metrics::kMetricCellularSignalStrengthBeforeDropMin = 0;
242const int Metrics::kMetricCellularSignalStrengthBeforeDropNumBuckets = 10;
243
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800244// static
Thieu Le5133b712013-02-19 14:47:21 -0800245const char Metrics::kMetricCorruptedProfile[] =
246 "Network.Shill.CorruptedProfile";
247
248// static
Paul Stewart91a43cb2013-03-02 21:34:15 -0800249const char Metrics::kMetricVpnDriver[] =
250 "Network.Shill.Vpn.Driver";
251const int Metrics::kMetricVpnDriverMax = Metrics::kVpnDriverMax;
252const char Metrics::kMetricVpnRemoteAuthenticationType[] =
253 "Network.Shill.Vpn.RemoteAuthenticationType";
254const int Metrics::kMetricVpnRemoteAuthenticationTypeMax =
255 Metrics::kVpnRemoteAuthenticationTypeMax;
256const char Metrics::kMetricVpnUserAuthenticationType[] =
257 "Network.Shill.Vpn.UserAuthenticationType";
258const int Metrics::kMetricVpnUserAuthenticationTypeMax =
259 Metrics::kVpnUserAuthenticationTypeMax;
260
mukesh agrawal132e96f2014-04-24 11:49:42 -0700261const char Metrics::kMetricExpiredLeaseLengthSecondsSuffix[] =
262 "ExpiredLeaseLengthSeconds";
Paul Stewart1f916e42013-12-23 09:52:54 -0800263const int Metrics::kMetricExpiredLeaseLengthSecondsMax =
264 7 * 24 * 60 * 60; // 7 days
265const int Metrics::kMetricExpiredLeaseLengthSecondsMin = 1;
266const int Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets =
267 Metrics::kMetricExpiredLeaseLengthSecondsMax;
268
Peter Qiu574996a2014-04-04 10:55:47 -0700269// static
270const char Metrics::kMetricWifiAutoConnectableServices[] =
Peter Qiu0dd90df2014-04-29 14:09:13 -0700271 "Network.Shill.WiFi.AutoConnectableServices";
Peter Qiu574996a2014-04-04 10:55:47 -0700272const int Metrics::kMetricWifiAutoConnectableServicesMax = 50;
273const int Metrics::kMetricWifiAutoConnectableServicesMin = 1;
274const int Metrics::kMetricWifiAutoConnectableServicesNumBuckets = 10;
275
276// static
277const char Metrics::kMetricWifiAvailableBSSes[] =
Peter Qiu0dd90df2014-04-29 14:09:13 -0700278 "Network.Shill.WiFi.AvailableBSSesAtConnect";
Peter Qiu574996a2014-04-04 10:55:47 -0700279const int Metrics::kMetricWifiAvailableBSSesMax = 50;
280const int Metrics::kMetricWifiAvailableBSSesMin = 1;
281const int Metrics::kMetricWifiAvailableBSSesNumBuckets = 10;
282
mukesh agrawalf7348732014-08-06 18:08:56 -0700283// static
284const char Metrics::kMetricWifiStoppedTxQueueReason[] =
285 "Network.Shill.WiFi.StoppedTxQueueReason";
286// Values are defined in mac80211_monitor.h.
287
288// static
289const char Metrics::kMetricWifiStoppedTxQueueLength[] =
290 "Network.Shill.WiFi.StoppedTxQueueLength";
291const int Metrics::kMetricWifiStoppedTxQueueLengthMax = 10000;
292const int Metrics::kMetricWifiStoppedTxQueueLengthMin = 1;
293const int Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets = 50;
294
Peter Qiu39d4af02014-04-14 12:24:01 -0700295// Number of services associated with currently connected network.
296const char Metrics::kMetricServicesOnSameNetwork[] =
297 "Network.Shill.ServicesOnSameNetwork";
298const int Metrics::kMetricServicesOnSameNetworkMax = 20;
299const int Metrics::kMetricServicesOnSameNetworkMin = 1;
300const int Metrics::kMetricServicesOnSameNetworkNumBuckets = 10;
301
Peter Qiue783f1c2014-05-02 11:42:33 -0700302// static
303const char Metrics::kMetricUserInitiatedEvents[] =
Peter Qiudc4e0992014-05-01 10:02:52 -0700304 "Network.Shill.UserInitiatedEvents";
Peter Qiue783f1c2014-05-02 11:42:33 -0700305
Peter Qiub9256f32014-05-09 15:27:29 -0700306// static
Peter Qiu8e430582014-04-30 14:12:37 -0700307const char Metrics::kMetricWifiTxBitrate[] =
308 "Network.Shill.WiFi.TransmitBitrateMbps";
309const int Metrics::kMetricWifiTxBitrateMax = 7000;
310const int Metrics::kMetricWifiTxBitrateMin = 1;
311const int Metrics::kMetricWifiTxBitrateNumBuckets = 100;
312
Peter Qiub9256f32014-05-09 15:27:29 -0700313// static
Peter Qiudc4e0992014-05-01 10:02:52 -0700314const char Metrics::kMetricWifiUserInitiatedConnectionResult[] =
315 "Network.Shill.WiFi.UserInitiatedConnectionResult";
316
Peter Qiub9256f32014-05-09 15:27:29 -0700317// static
Peter Qiud87179e2014-07-10 18:29:22 -0700318const char Metrics::kMetricWifiUserInitiatedConnectionFailureReason[] =
319 "Network.Shill.WiFi.UserInitiatedConnectionFailureReason";
320
321// static
Peter Qiuf18e7712014-05-20 09:59:46 -0700322const char Metrics::kMetricFallbackDNSTestResultSuffix[] =
323 "FallbackDNSTestResult";
Peter Qiub9256f32014-05-09 15:27:29 -0700324
Peter Qiudc335f82014-05-15 10:33:17 -0700325// static
326const char Metrics::kMetricNetworkProblemDetectedSuffix[] =
327 "NetworkProblemDetected";
328
Peter Qiu700de642014-07-14 16:31:30 -0700329// static
330const char Metrics::kMetricDeviceConnectionStatus[] =
331 "Network.Shill.DeviceConnectionStatus";
332
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700333// static
334const char Metrics::kMetricDhcpClientStatus[] =
Paul Stewarta72a79c2014-07-21 13:52:03 -0700335 "Network.Shill.DHCPClientStatus";
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700336
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800337Metrics::Metrics(EventDispatcher *dispatcher)
338 : dispatcher_(dispatcher),
339 library_(&metrics_library_),
Thieu Lea20cbc22012-01-09 22:01:43 +0000340 last_default_technology_(Technology::kUnknown),
341 was_online_(false),
342 time_online_timer_(new chromeos_metrics::Timer),
Thieu Leb84ba342012-03-02 15:15:19 -0800343 time_to_drop_timer_(new chromeos_metrics::Timer),
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200344 time_resume_to_ready_timer_(new chromeos_metrics::Timer),
Arman Ugurayab22c162012-10-08 19:08:38 -0700345 time_termination_actions_timer(new chromeos_metrics::Timer),
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200346 collect_bootstats_(true) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000347 metrics_library_.Init();
348 chromeos_metrics::TimerReporter::set_metrics_lib(library_);
349}
350
351Metrics::~Metrics() {}
352
353// static
Ben Chan7fab8972014-08-10 17:14:46 -0700354Metrics::WiFiChannel Metrics::WiFiFrequencyToChannel(uint16_t frequency) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000355 WiFiChannel channel = kWiFiChannelUndef;
356 if (kWiFiFrequency2412 <= frequency && frequency <= kWiFiFrequency2472) {
357 if (((frequency - kWiFiFrequency2412) % kWiFiBandwidth5MHz) == 0)
358 channel = static_cast<WiFiChannel>(
359 kWiFiChannel2412 +
360 (frequency - kWiFiFrequency2412) / kWiFiBandwidth5MHz);
361 } else if (frequency == kWiFiFrequency2484) {
362 channel = kWiFiChannel2484;
363 } else if (kWiFiFrequency5170 <= frequency &&
364 frequency <= kWiFiFrequency5230) {
365 if ((frequency % kWiFiBandwidth20MHz) == 0)
366 channel = static_cast<WiFiChannel>(
367 kWiFiChannel5180 +
368 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
369 if ((frequency % kWiFiBandwidth20MHz) == 10)
370 channel = static_cast<WiFiChannel>(
371 kWiFiChannel5170 +
372 (frequency - kWiFiFrequency5170) / kWiFiBandwidth20MHz);
373 } else if (kWiFiFrequency5240 <= frequency &&
374 frequency <= kWiFiFrequency5320) {
375 if (((frequency - kWiFiFrequency5180) % kWiFiBandwidth20MHz) == 0)
376 channel = static_cast<WiFiChannel>(
377 kWiFiChannel5180 +
378 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
379 } else if (kWiFiFrequency5500 <= frequency &&
380 frequency <= kWiFiFrequency5700) {
381 if (((frequency - kWiFiFrequency5500) % kWiFiBandwidth20MHz) == 0)
382 channel = static_cast<WiFiChannel>(
383 kWiFiChannel5500 +
384 (frequency - kWiFiFrequency5500) / kWiFiBandwidth20MHz);
385 } else if (kWiFiFrequency5745 <= frequency &&
386 frequency <= kWiFiFrequency5825) {
387 if (((frequency - kWiFiFrequency5745) % kWiFiBandwidth20MHz) == 0)
388 channel = static_cast<WiFiChannel>(
389 kWiFiChannel5745 +
390 (frequency - kWiFiFrequency5745) / kWiFiBandwidth20MHz);
391 }
392 CHECK(kWiFiChannelUndef <= channel && channel < kWiFiChannelMax);
393
394 if (channel == kWiFiChannelUndef)
395 LOG(WARNING) << "no mapping for frequency " << frequency;
396 else
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700397 SLOG(Metrics, 3) << "mapped frequency " << frequency
398 << " to enum bucket " << channel;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000399
400 return channel;
401}
402
Thieu Lead1ec2c2012-01-05 23:39:48 +0000403// static
404Metrics::WiFiSecurity Metrics::WiFiSecurityStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700405 const string &security) {
Ben Chan923a5022013-09-20 11:23:23 -0700406 if (security == kSecurityNone) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000407 return kWiFiSecurityNone;
Ben Chan923a5022013-09-20 11:23:23 -0700408 } else if (security == kSecurityWep) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000409 return kWiFiSecurityWep;
Ben Chan923a5022013-09-20 11:23:23 -0700410 } else if (security == kSecurityWpa) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000411 return kWiFiSecurityWpa;
Ben Chan923a5022013-09-20 11:23:23 -0700412 } else if (security == kSecurityRsn) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000413 return kWiFiSecurityRsn;
Ben Chan923a5022013-09-20 11:23:23 -0700414 } else if (security == kSecurity8021x) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000415 return kWiFiSecurity8021x;
Ben Chan923a5022013-09-20 11:23:23 -0700416 } else if (security == kSecurityPsk) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000417 return kWiFiSecurityPsk;
418 } else {
419 return kWiFiSecurityUnknown;
420 }
421}
422
Thieu Le85e050b2012-03-13 15:04:38 -0700423// static
Paul Stewarte4cedde2013-07-17 08:56:44 -0700424Metrics::WiFiApMode Metrics::WiFiApModeStringToEnum(const string &ap_mode) {
Ben Chan923a5022013-09-20 11:23:23 -0700425 if (ap_mode == kModeManaged) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700426 return kWiFiApModeManaged;
Ben Chan923a5022013-09-20 11:23:23 -0700427 } else if (ap_mode == kModeAdhoc) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700428 return kWiFiApModeAdHoc;
429 } else {
430 return kWiFiApModeUnknown;
431 }
432}
433
434// static
Paul Stewart21f40962013-03-01 14:27:28 -0800435Metrics::EapOuterProtocol Metrics::EapOuterProtocolStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700436 const string &outer) {
Ben Chan923a5022013-09-20 11:23:23 -0700437 if (outer == kEapMethodPEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800438 return kEapOuterProtocolPeap;
Ben Chan923a5022013-09-20 11:23:23 -0700439 } else if (outer == kEapMethodTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800440 return kEapOuterProtocolTls;
Ben Chan923a5022013-09-20 11:23:23 -0700441 } else if (outer == kEapMethodTTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800442 return kEapOuterProtocolTtls;
Ben Chan923a5022013-09-20 11:23:23 -0700443 } else if (outer == kEapMethodLEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800444 return kEapOuterProtocolLeap;
445 } else {
446 return kEapOuterProtocolUnknown;
447 }
448}
449
450// static
451Metrics::EapInnerProtocol Metrics::EapInnerProtocolStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700452 const string &inner) {
Paul Stewart21f40962013-03-01 14:27:28 -0800453 if (inner.empty()) {
454 return kEapInnerProtocolNone;
Ben Chan923a5022013-09-20 11:23:23 -0700455 } else if (inner == kEapPhase2AuthPEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800456 return kEapInnerProtocolPeapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700457 } else if (inner == kEapPhase2AuthPEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800458 return kEapInnerProtocolPeapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700459 } else if (inner == kEapPhase2AuthTTLSEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800460 return kEapInnerProtocolTtlsEapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700461 } else if (inner == kEapPhase2AuthTTLSEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800462 return kEapInnerProtocolTtlsEapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700463 } else if (inner == kEapPhase2AuthTTLSMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800464 return kEapInnerProtocolTtlsMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700465 } else if (inner == kEapPhase2AuthTTLSMSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800466 return kEapInnerProtocolTtlsMschap;
Ben Chan923a5022013-09-20 11:23:23 -0700467 } else if (inner == kEapPhase2AuthTTLSPAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800468 return kEapInnerProtocolTtlsPap;
Ben Chan923a5022013-09-20 11:23:23 -0700469 } else if (inner == kEapPhase2AuthTTLSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800470 return kEapInnerProtocolTtlsChap;
471 } else {
472 return kEapInnerProtocolUnknown;
473 }
474}
475
476// static
Thieu Le85e050b2012-03-13 15:04:38 -0700477Metrics::PortalResult Metrics::PortalDetectionResultToEnum(
478 const PortalDetector::Result &result) {
479 DCHECK(result.final);
480 PortalResult retval = kPortalResultUnknown;
481 // The only time we should end a successful portal detection is when we're
482 // in the Content phase. If we end with kStatusSuccess in any other phase,
483 // then this indicates that something bad has happened.
484 switch (result.phase) {
485 case PortalDetector::kPhaseDNS:
486 if (result.status == PortalDetector::kStatusFailure)
487 retval = kPortalResultDNSFailure;
488 else if (result.status == PortalDetector::kStatusTimeout)
489 retval = kPortalResultDNSTimeout;
490 else
491 LOG(DFATAL) << __func__ << ": Final result status " << result.status
492 << " is not allowed in the DNS phase";
493 break;
494
495 case PortalDetector::kPhaseConnection:
496 if (result.status == PortalDetector::kStatusFailure)
497 retval = kPortalResultConnectionFailure;
498 else if (result.status == PortalDetector::kStatusTimeout)
499 retval = kPortalResultConnectionTimeout;
500 else
501 LOG(DFATAL) << __func__ << ": Final result status " << result.status
502 << " is not allowed in the Connection phase";
503 break;
504
505 case PortalDetector::kPhaseHTTP:
506 if (result.status == PortalDetector::kStatusFailure)
507 retval = kPortalResultHTTPFailure;
508 else if (result.status == PortalDetector::kStatusTimeout)
509 retval = kPortalResultHTTPTimeout;
510 else
511 LOG(DFATAL) << __func__ << ": Final result status " << result.status
512 << " is not allowed in the HTTP phase";
513 break;
514
515 case PortalDetector::kPhaseContent:
516 if (result.status == PortalDetector::kStatusSuccess)
517 retval = kPortalResultSuccess;
518 else if (result.status == PortalDetector::kStatusFailure)
519 retval = kPortalResultContentFailure;
520 else if (result.status == PortalDetector::kStatusTimeout)
521 retval = kPortalResultContentTimeout;
522 else
523 LOG(DFATAL) << __func__ << ": Final result status " << result.status
524 << " is not allowed in the Content phase";
525 break;
526
527 case PortalDetector::kPhaseUnknown:
528 retval = kPortalResultUnknown;
529 break;
530
531 default:
532 LOG(DFATAL) << __func__ << ": Invalid phase " << result.phase;
533 break;
534 }
535
536 return retval;
537}
538
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800539void Metrics::Start() {
540 SLOG(Metrics, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800541}
542
543void Metrics::Stop() {
544 SLOG(Metrics, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800545}
546
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700547void Metrics::RegisterService(const Service &service) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700548 SLOG(Metrics, 2) << __func__;
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700549 LOG_IF(WARNING, ContainsKey(services_metrics_, &service))
550 << "Repeatedly registering " << service.unique_name();
mukesh agrawal6cfe53f2013-08-13 13:39:01 -0700551 shared_ptr<ServiceMetrics> service_metrics(new ServiceMetrics());
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700552 services_metrics_[&service] = service_metrics;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000553 InitializeCommonServiceMetrics(service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000554}
555
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700556void Metrics::DeregisterService(const Service &service) {
557 services_metrics_.erase(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000558}
559
560void Metrics::AddServiceStateTransitionTimer(
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700561 const Service &service,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000562 const string &histogram_name,
563 Service::ConnectState start_state,
564 Service::ConnectState stop_state) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700565 SLOG(Metrics, 2) << __func__ << ": adding " << histogram_name << " for "
566 << Service::ConnectStateToString(start_state) << " -> "
567 << Service::ConnectStateToString(stop_state);
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700568 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000569 if (it == services_metrics_.end()) {
Ben Chanfad4a0b2012-04-18 15:49:59 -0700570 SLOG(Metrics, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000571 DCHECK(false);
572 return;
573 }
574 ServiceMetrics *service_metrics = it->second.get();
575 CHECK(start_state < stop_state);
576 chromeos_metrics::TimerReporter *timer =
577 new chromeos_metrics::TimerReporter(histogram_name,
Thieu Lea20cbc22012-01-09 22:01:43 +0000578 kTimerHistogramMillisecondsMin,
579 kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000580 kTimerHistogramNumBuckets);
581 service_metrics->timers.push_back(timer); // passes ownership.
582 service_metrics->start_on_state[start_state].push_back(timer);
583 service_metrics->stop_on_state[stop_state].push_back(timer);
584}
585
Thieu Lea20cbc22012-01-09 22:01:43 +0000586void Metrics::NotifyDefaultServiceChanged(const Service *service) {
587 base::TimeDelta elapsed_seconds;
588
589 Technology::Identifier technology = (service) ? service->technology() :
590 Technology::kUnknown;
591 if (technology != last_default_technology_) {
592 if (last_default_technology_ != Technology::kUnknown) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700593 string histogram = GetFullMetricName(kMetricTimeOnlineSecondsSuffix,
Thieu Lea20cbc22012-01-09 22:01:43 +0000594 last_default_technology_);
595 time_online_timer_->GetElapsedTime(&elapsed_seconds);
596 SendToUMA(histogram,
597 elapsed_seconds.InSeconds(),
598 kMetricTimeOnlineSecondsMin,
599 kMetricTimeOnlineSecondsMax,
600 kTimerHistogramNumBuckets);
601 }
602 last_default_technology_ = technology;
603 time_online_timer_->Start();
604 }
605
Thieu Lea20cbc22012-01-09 22:01:43 +0000606 // Ignore changes that are not online/offline transitions; e.g.
607 // switching between wired and wireless. TimeToDrop measures
608 // time online regardless of how we are connected.
609 if ((service == NULL && !was_online_) || (service != NULL && was_online_))
610 return;
611
612 if (service == NULL) {
613 time_to_drop_timer_->GetElapsedTime(&elapsed_seconds);
614 SendToUMA(kMetricTimeToDropSeconds,
615 elapsed_seconds.InSeconds(),
616 kMetricTimeToDropSecondsMin,
617 kMetricTimeToDropSecondsMax,
618 kTimerHistogramNumBuckets);
619 } else {
620 time_to_drop_timer_->Start();
621 }
622
623 was_online_ = (service != NULL);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000624}
625
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700626void Metrics::NotifyServiceStateChanged(const Service &service,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000627 Service::ConnectState new_state) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700628 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000629 if (it == services_metrics_.end()) {
Ben Chanfad4a0b2012-04-18 15:49:59 -0700630 SLOG(Metrics, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000631 DCHECK(false);
632 return;
633 }
634 ServiceMetrics *service_metrics = it->second.get();
635 UpdateServiceStateTransitionMetrics(service_metrics, new_state);
636
637 if (new_state == Service::kStateFailure)
638 SendServiceFailure(service);
639
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200640 if (collect_bootstats_) {
Ben Chana0ddf462014-02-06 11:32:42 -0800641 bootstat_log(base::StringPrintf("network-%s-%s",
642 Technology::NameFromIdentifier(
643 service.technology()).c_str(),
644 service.GetStateString().c_str()).c_str());
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200645 }
646
Paul Stewart20088d82012-02-16 06:58:55 -0800647 if (new_state != Service::kStateConnected)
Thieu Le48e6d6d2011-12-06 00:40:27 +0000648 return;
649
Thieu Leb84ba342012-03-02 15:15:19 -0800650 base::TimeDelta time_resume_to_ready;
651 time_resume_to_ready_timer_->GetElapsedTime(&time_resume_to_ready);
652 time_resume_to_ready_timer_->Reset();
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700653 service.SendPostReadyStateMetrics(time_resume_to_ready.InMilliseconds());
Thieu Le48e6d6d2011-12-06 00:40:27 +0000654}
655
mukesh agrawal132e96f2014-04-24 11:49:42 -0700656string Metrics::GetFullMetricName(const char *metric_suffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000657 Technology::Identifier technology_id) {
658 string technology = Technology::NameFromIdentifier(technology_id);
659 technology[0] = base::ToUpperASCII(technology[0]);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700660 return base::StringPrintf("%s.%s.%s", kMetricPrefix, technology.c_str(),
661 metric_suffix);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000662}
663
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700664void Metrics::NotifyServiceDisconnect(const Service &service) {
665 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700666 string histogram = GetFullMetricName(kMetricDisconnectSuffix, technology);
Thieu Le67370f62012-02-14 23:01:42 +0000667 SendToUMA(histogram,
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700668 service.explicitly_disconnected(),
Thieu Le67370f62012-02-14 23:01:42 +0000669 kMetricDisconnectMin,
670 kMetricDisconnectMax,
671 kMetricDisconnectNumBuckets);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000672}
673
Wade Guthrie9ec08062013-09-25 15:22:24 -0700674void Metrics::NotifySignalAtDisconnect(const Service &service,
675 int16_t signal_strength) {
676 // Negate signal_strength (goes from dBm to -dBm) because the metrics don't
677 // seem to handle negative values well. Now everything's positive.
678 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700679 string histogram = GetFullMetricName(kMetricSignalAtDisconnectSuffix,
680 technology);
Wade Guthrie9ec08062013-09-25 15:22:24 -0700681 SendToUMA(histogram,
682 -signal_strength,
683 kMetricSignalAtDisconnectMin,
684 kMetricSignalAtDisconnectMax,
685 kMetricSignalAtDisconnectNumBuckets);
686}
687
Daniel Eratfac09532014-04-17 20:25:59 -0700688void Metrics::NotifySuspendDone() {
689 time_resume_to_ready_timer_->Start();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000690}
691
Arman Ugurayab22c162012-10-08 19:08:38 -0700692void Metrics::NotifyTerminationActionsStarted(
693 TerminationActionReason /*reason*/) {
694 if (time_termination_actions_timer->HasStarted())
695 return;
696 time_termination_actions_timer->Start();
697}
698
699void Metrics::NotifyTerminationActionsCompleted(
700 TerminationActionReason reason, bool success) {
701 if (!time_termination_actions_timer->HasStarted())
702 return;
703
704 int result = success ? kTerminationActionResultSuccess :
705 kTerminationActionResultFailure;
706
707 base::TimeDelta elapsed_time;
708 time_termination_actions_timer->GetElapsedTime(&elapsed_time);
709 time_termination_actions_timer->Reset();
710 string time_metric, result_metric;
711 switch (reason) {
712 case kTerminationActionReasonSuspend:
713 time_metric = kMetricTerminationActionTimeOnSuspend;
714 result_metric = kMetricTerminationActionResultOnSuspend;
715 break;
716 case kTerminationActionReasonTerminate:
717 time_metric = kMetricTerminationActionTimeOnTerminate;
718 result_metric = kMetricTerminationActionResultOnTerminate;
719 break;
720 }
721
722 SendToUMA(time_metric,
723 elapsed_time.InMilliseconds(),
724 kMetricTerminationActionTimeMillisecondsMin,
725 kMetricTerminationActionTimeMillisecondsMax,
726 kTimerHistogramNumBuckets);
727
728 SendEnumToUMA(result_metric,
729 result,
730 kTerminationActionResultMax);
731}
732
Paul Stewartff845fc2012-08-07 07:28:44 -0700733void Metrics::NotifyLinkMonitorFailure(
Paul Stewart0443aa52012-08-09 10:43:50 -0700734 Technology::Identifier technology,
735 LinkMonitorFailure failure,
Paul Stewartf1961f82012-09-11 20:45:39 -0700736 int seconds_to_failure,
737 int broadcast_error_count,
738 int unicast_error_count) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700739 string histogram = GetFullMetricName(kMetricLinkMonitorFailureSuffix,
Paul Stewartff845fc2012-08-07 07:28:44 -0700740 technology);
741 SendEnumToUMA(histogram, failure, kLinkMonitorFailureMax);
Paul Stewart0443aa52012-08-09 10:43:50 -0700742
743 if (failure == kLinkMonitorFailureThresholdReached) {
744 if (seconds_to_failure > kMetricLinkMonitorSecondsToFailureMax) {
745 seconds_to_failure = kMetricLinkMonitorSecondsToFailureMax;
746 }
mukesh agrawal132e96f2014-04-24 11:49:42 -0700747 histogram = GetFullMetricName(kMetricLinkMonitorSecondsToFailureSuffix,
Paul Stewart0443aa52012-08-09 10:43:50 -0700748 technology);
749 SendToUMA(histogram,
750 seconds_to_failure,
751 kMetricLinkMonitorSecondsToFailureMin,
752 kMetricLinkMonitorSecondsToFailureMax,
753 kMetricLinkMonitorSecondsToFailureNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700754 histogram = GetFullMetricName(
755 kMetricLinkMonitorBroadcastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700756 SendToUMA(histogram,
757 broadcast_error_count,
758 kMetricLinkMonitorErrorCountMin,
759 kMetricLinkMonitorErrorCountMax,
760 kMetricLinkMonitorErrorCountNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700761 histogram = GetFullMetricName(
762 kMetricLinkMonitorUnicastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700763 SendToUMA(histogram,
764 unicast_error_count,
765 kMetricLinkMonitorErrorCountMin,
766 kMetricLinkMonitorErrorCountMax,
767 kMetricLinkMonitorErrorCountNumBuckets);
768 }
Paul Stewartff845fc2012-08-07 07:28:44 -0700769}
770
771void Metrics::NotifyLinkMonitorResponseTimeSampleAdded(
772 Technology::Identifier technology,
Paul Stewartf1961f82012-09-11 20:45:39 -0700773 int response_time_milliseconds) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700774 string histogram = GetFullMetricName(
775 kMetricLinkMonitorResponseTimeSampleSuffix, technology);
Paul Stewartff845fc2012-08-07 07:28:44 -0700776 SendToUMA(histogram,
777 response_time_milliseconds,
778 kMetricLinkMonitorResponseTimeSampleMin,
779 kMetricLinkMonitorResponseTimeSampleMax,
780 kMetricLinkMonitorResponseTimeSampleNumBuckets);
781}
782
Wade Guthried4977f22012-08-22 12:37:54 -0700783void Metrics::Notify80211Disconnect(WiFiDisconnectByWhom by_whom,
784 IEEE_80211::WiFiReasonCode reason) {
785 string metric_disconnect_reason;
786 string metric_disconnect_type;
787 WiFiStatusType type;
788
789 if (by_whom == kDisconnectedByAp) {
790 metric_disconnect_reason = kMetricLinkApDisconnectReason;
791 metric_disconnect_type = kMetricLinkApDisconnectType;
792 type = kStatusCodeTypeByAp;
793 } else {
794 metric_disconnect_reason = kMetricLinkClientDisconnectReason;
795 metric_disconnect_type = kMetricLinkClientDisconnectType;
Wade Guthrie60a37062013-04-02 11:39:09 -0700796 switch (reason) {
Wade Guthried4977f22012-08-22 12:37:54 -0700797 case IEEE_80211::kReasonCodeSenderHasLeft:
798 case IEEE_80211::kReasonCodeDisassociatedHasLeft:
799 type = kStatusCodeTypeByUser;
800 break;
801
802 case IEEE_80211::kReasonCodeInactivity:
803 type = kStatusCodeTypeConsideredDead;
804 break;
805
806 default:
807 type = kStatusCodeTypeByClient;
808 break;
809 }
810 }
811 SendEnumToUMA(metric_disconnect_reason, reason,
812 IEEE_80211::kStatusCodeMax);
813 SendEnumToUMA(metric_disconnect_type, type, kStatusCodeTypeMax);
814}
815
Thieu Lec8078a62013-01-22 18:01:12 -0800816void Metrics::RegisterDevice(int interface_index,
817 Technology::Identifier technology) {
Thieu Le9abd6742013-01-23 23:35:37 -0800818 SLOG(Metrics, 2) << __func__ << ": " << interface_index;
Thieu Lec8078a62013-01-22 18:01:12 -0800819 shared_ptr<DeviceMetrics> device_metrics(new DeviceMetrics);
820 devices_metrics_[interface_index] = device_metrics;
Thieu Le9abd6742013-01-23 23:35:37 -0800821 device_metrics->technology = technology;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700822 string histogram = GetFullMetricName(
823 kMetricTimeToInitializeMillisecondsSuffix, technology);
Thieu Lec8078a62013-01-22 18:01:12 -0800824 device_metrics->initialization_timer.reset(
825 new chromeos_metrics::TimerReporter(
826 histogram,
827 kMetricTimeToInitializeMillisecondsMin,
828 kMetricTimeToInitializeMillisecondsMax,
829 kMetricTimeToInitializeMillisecondsNumBuckets));
830 device_metrics->initialization_timer->Start();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700831 histogram = GetFullMetricName(kMetricTimeToEnableMillisecondsSuffix,
Thieu Lece4483e2013-01-23 15:12:03 -0800832 technology);
833 device_metrics->enable_timer.reset(
834 new chromeos_metrics::TimerReporter(
835 histogram,
836 kMetricTimeToEnableMillisecondsMin,
837 kMetricTimeToEnableMillisecondsMax,
838 kMetricTimeToEnableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700839 histogram = GetFullMetricName(kMetricTimeToDisableMillisecondsSuffix,
Thieu Lea2519bf2013-01-23 16:51:54 -0800840 technology);
841 device_metrics->disable_timer.reset(
842 new chromeos_metrics::TimerReporter(
843 histogram,
844 kMetricTimeToDisableMillisecondsMin,
845 kMetricTimeToDisableMillisecondsMax,
846 kMetricTimeToDisableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700847 histogram = GetFullMetricName(kMetricTimeToScanMillisecondsSuffix,
Thieu Le18c11072013-01-28 17:21:37 -0800848 technology);
849 device_metrics->scan_timer.reset(
850 new chromeos_metrics::TimerReporter(
851 histogram,
852 kMetricTimeToScanMillisecondsMin,
853 kMetricTimeToScanMillisecondsMax,
854 kMetricTimeToScanMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700855 histogram = GetFullMetricName(kMetricTimeToConnectMillisecondsSuffix,
Thieu Lecdb5a212013-01-25 11:17:18 -0800856 technology);
857 device_metrics->connect_timer.reset(
858 new chromeos_metrics::TimerReporter(
859 histogram,
860 kMetricTimeToConnectMillisecondsMin,
861 kMetricTimeToConnectMillisecondsMax,
862 kMetricTimeToConnectMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700863 histogram = GetFullMetricName(kMetricTimeToScanAndConnectMillisecondsSuffix,
Wade Guthrie44f290d2013-05-28 10:16:25 -0700864 technology);
865 device_metrics->scan_connect_timer.reset(
866 new chromeos_metrics::TimerReporter(
867 histogram,
868 kMetricTimeToScanMillisecondsMin,
869 kMetricTimeToScanMillisecondsMax +
870 kMetricTimeToConnectMillisecondsMax,
871 kMetricTimeToScanMillisecondsNumBuckets +
872 kMetricTimeToConnectMillisecondsNumBuckets));
Thieu Le7cf36b02013-01-30 17:15:56 -0800873 device_metrics->auto_connect_timer.reset(
874 new chromeos_metrics::TimerReporter(
875 kMetricCellularAutoConnectTotalTime,
876 kMetricCellularAutoConnectTotalTimeMin,
877 kMetricCellularAutoConnectTotalTimeMax,
878 kMetricCellularAutoConnectTotalTimeNumBuckets));
Thieu Lec8078a62013-01-22 18:01:12 -0800879}
880
Thieu Le9abd6742013-01-23 23:35:37 -0800881bool Metrics::IsDeviceRegistered(int interface_index,
882 Technology::Identifier technology) {
883 SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index
884 << ", technology: " << technology;
885 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
886 if (device_metrics == NULL)
887 return false;
888 // Make sure the device technologies match.
889 return (technology == device_metrics->technology);
890}
891
Thieu Lec8078a62013-01-22 18:01:12 -0800892void Metrics::DeregisterDevice(int interface_index) {
Thieu Le9abd6742013-01-23 23:35:37 -0800893 SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index;
Thieu Lec8078a62013-01-22 18:01:12 -0800894 devices_metrics_.erase(interface_index);
895}
896
897void Metrics::NotifyDeviceInitialized(int interface_index) {
Thieu Lece4483e2013-01-23 15:12:03 -0800898 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
899 if (device_metrics == NULL)
Thieu Lec8078a62013-01-22 18:01:12 -0800900 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700901 if (!device_metrics->initialization_timer->Stop())
902 return;
Thieu Lec8078a62013-01-22 18:01:12 -0800903 device_metrics->initialization_timer->ReportMilliseconds();
904}
905
Thieu Lece4483e2013-01-23 15:12:03 -0800906void Metrics::NotifyDeviceEnableStarted(int interface_index) {
907 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
908 if (device_metrics == NULL)
909 return;
910 device_metrics->enable_timer->Start();
911}
912
913void Metrics::NotifyDeviceEnableFinished(int interface_index) {
914 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
915 if (device_metrics == NULL)
916 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700917 if (!device_metrics->enable_timer->Stop())
918 return;
Thieu Lece4483e2013-01-23 15:12:03 -0800919 device_metrics->enable_timer->ReportMilliseconds();
920}
921
Thieu Lea2519bf2013-01-23 16:51:54 -0800922void Metrics::NotifyDeviceDisableStarted(int interface_index) {
923 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
924 if (device_metrics == NULL)
925 return;
926 device_metrics->disable_timer->Start();
927}
928
929void Metrics::NotifyDeviceDisableFinished(int interface_index) {
930 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
931 if (device_metrics == NULL)
932 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700933 if (!device_metrics->disable_timer->Stop())
934 return;
Thieu Lea2519bf2013-01-23 16:51:54 -0800935 device_metrics->disable_timer->ReportMilliseconds();
936}
937
Thieu Le18c11072013-01-28 17:21:37 -0800938void Metrics::NotifyDeviceScanStarted(int interface_index) {
939 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
940 if (device_metrics == NULL)
941 return;
Thieu Le18c11072013-01-28 17:21:37 -0800942 device_metrics->scan_timer->Start();
Wade Guthrie44f290d2013-05-28 10:16:25 -0700943 device_metrics->scan_connect_timer->Start();
Thieu Le18c11072013-01-28 17:21:37 -0800944}
945
946void Metrics::NotifyDeviceScanFinished(int interface_index) {
947 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
948 if (device_metrics == NULL)
949 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700950 if (!device_metrics->scan_timer->Stop())
951 return;
Wade Guthrie68d41092013-04-02 12:56:02 -0700952 // Don't send TimeToScan metrics if the elapsed time exceeds the max metrics
953 // value. Huge scan times usually mean something's gone awry; for cellular,
954 // for instance, this usually means that the modem is in an area without
955 // service and we're not interested in this scenario.
Thieu Le18c11072013-01-28 17:21:37 -0800956 base::TimeDelta elapsed_time;
957 device_metrics->scan_timer->GetElapsedTime(&elapsed_time);
958 if (elapsed_time.InMilliseconds() <= kMetricTimeToScanMillisecondsMax)
959 device_metrics->scan_timer->ReportMilliseconds();
960}
961
Wade Guthrie44f290d2013-05-28 10:16:25 -0700962void Metrics::ResetScanTimer(int interface_index) {
963 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
964 if (device_metrics == NULL)
965 return;
966 device_metrics->scan_timer->Reset();
967}
968
Thieu Le7cf36b02013-01-30 17:15:56 -0800969void Metrics::NotifyDeviceConnectStarted(int interface_index,
970 bool is_auto_connecting) {
Thieu Lecdb5a212013-01-25 11:17:18 -0800971 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
972 if (device_metrics == NULL)
973 return;
974 device_metrics->connect_timer->Start();
Thieu Le7cf36b02013-01-30 17:15:56 -0800975
976 if (is_auto_connecting) {
977 device_metrics->auto_connect_tries++;
978 if (device_metrics->auto_connect_tries == 1)
979 device_metrics->auto_connect_timer->Start();
980 } else {
981 AutoConnectMetricsReset(device_metrics);
982 }
Thieu Lecdb5a212013-01-25 11:17:18 -0800983}
984
985void Metrics::NotifyDeviceConnectFinished(int interface_index) {
986 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
987 if (device_metrics == NULL)
988 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700989 if (!device_metrics->connect_timer->Stop())
990 return;
Thieu Lecdb5a212013-01-25 11:17:18 -0800991 device_metrics->connect_timer->ReportMilliseconds();
Thieu Le7cf36b02013-01-30 17:15:56 -0800992
993 if (device_metrics->auto_connect_tries > 0) {
Wade Guthrie091c41c2013-03-22 15:48:53 -0700994 if (!device_metrics->auto_connect_timer->Stop())
995 return;
Thieu Le7cf36b02013-01-30 17:15:56 -0800996 base::TimeDelta elapsed_time;
997 device_metrics->auto_connect_timer->GetElapsedTime(&elapsed_time);
998 if (elapsed_time.InMilliseconds() > kMetricCellularAutoConnectTotalTimeMax)
999 return;
1000 device_metrics->auto_connect_timer->ReportMilliseconds();
1001 SendToUMA(kMetricCellularAutoConnectTries,
1002 device_metrics->auto_connect_tries,
1003 kMetricCellularAutoConnectTriesMin,
1004 kMetricCellularAutoConnectTriesMax,
1005 kMetricCellularAutoConnectTriesNumBuckets);
1006 AutoConnectMetricsReset(device_metrics);
1007 }
Wade Guthrie44f290d2013-05-28 10:16:25 -07001008
1009 if (!device_metrics->scan_connect_timer->Stop())
1010 return;
Wade Guthrie44f290d2013-05-28 10:16:25 -07001011 device_metrics->scan_connect_timer->ReportMilliseconds();
1012}
1013
1014void Metrics::ResetConnectTimer(int interface_index) {
1015 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
1016 if (device_metrics == NULL)
1017 return;
1018 device_metrics->connect_timer->Reset();
1019 device_metrics->scan_connect_timer->Reset();
Thieu Lecdb5a212013-01-25 11:17:18 -08001020}
1021
Prathmesh Prabhu08757aa2013-05-15 17:17:33 -07001022void Metrics::Notify3GPPRegistrationDelayedDropPosted() {
1023 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1024 kCellular3GPPRegistrationDelayedDropPosted,
1025 kCellular3GPPRegistrationDelayedDropMax);
1026}
1027
1028void Metrics::Notify3GPPRegistrationDelayedDropCanceled() {
1029 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1030 kCellular3GPPRegistrationDelayedDropCanceled,
1031 kCellular3GPPRegistrationDelayedDropMax);
1032}
1033
mukesh agrawal09e08112013-08-16 13:26:44 -07001034void Metrics::NotifyCellularDeviceDrop(const string &network_technology,
Ben Chan7fab8972014-08-10 17:14:46 -07001035 uint16_t signal_strength) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001036 SLOG(Metrics, 2) << __func__ << ": " << network_technology
1037 << ", " << signal_strength;
1038 CellularDropTechnology drop_technology = kCellularDropTechnologyUnknown;
Ben Chan923a5022013-09-20 11:23:23 -07001039 if (network_technology == kNetworkTechnology1Xrtt) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001040 drop_technology = kCellularDropTechnology1Xrtt;
Ben Chan923a5022013-09-20 11:23:23 -07001041 } else if (network_technology == kNetworkTechnologyEdge) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001042 drop_technology = kCellularDropTechnologyEdge;
Ben Chan923a5022013-09-20 11:23:23 -07001043 } else if (network_technology == kNetworkTechnologyEvdo) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001044 drop_technology = kCellularDropTechnologyEvdo;
Ben Chan923a5022013-09-20 11:23:23 -07001045 } else if (network_technology == kNetworkTechnologyGprs) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001046 drop_technology = kCellularDropTechnologyGprs;
Ben Chan923a5022013-09-20 11:23:23 -07001047 } else if (network_technology == kNetworkTechnologyGsm) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001048 drop_technology = kCellularDropTechnologyGsm;
Ben Chan923a5022013-09-20 11:23:23 -07001049 } else if (network_technology == kNetworkTechnologyHspa) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001050 drop_technology = kCellularDropTechnologyHspa;
Ben Chan923a5022013-09-20 11:23:23 -07001051 } else if (network_technology == kNetworkTechnologyHspaPlus) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001052 drop_technology = kCellularDropTechnologyHspaPlus;
Ben Chan923a5022013-09-20 11:23:23 -07001053 } else if (network_technology == kNetworkTechnologyLte) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001054 drop_technology = kCellularDropTechnologyLte;
Ben Chan923a5022013-09-20 11:23:23 -07001055 } else if (network_technology == kNetworkTechnologyUmts) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001056 drop_technology = kCellularDropTechnologyUmts;
1057 }
1058 SendEnumToUMA(kMetricCellularDrop,
1059 drop_technology,
1060 kCellularDropTechnologyMax);
1061 SendToUMA(kMetricCellularSignalStrengthBeforeDrop,
1062 signal_strength,
1063 kMetricCellularSignalStrengthBeforeDropMin,
1064 kMetricCellularSignalStrengthBeforeDropMax,
1065 kMetricCellularSignalStrengthBeforeDropNumBuckets);
1066}
1067
Thieu Leb7aa5f72013-01-31 15:57:48 -08001068void Metrics::NotifyCellularDeviceFailure(const Error &error) {
1069 library_->SendUserActionToUMA(
1070 kMetricCellularFailureReason + error.message());
1071}
1072
Thieu Le91fccf62013-04-22 15:23:16 -07001073void Metrics::NotifyCellularOutOfCredits(
1074 Metrics::CellularOutOfCreditsReason reason) {
1075 SendEnumToUMA(kMetricCellularOutOfCreditsReason,
1076 reason,
1077 kCellularOutOfCreditsReasonMax);
1078}
1079
Thieu Le5133b712013-02-19 14:47:21 -08001080void Metrics::NotifyCorruptedProfile() {
1081 SendEnumToUMA(kMetricCorruptedProfile,
1082 kCorruptedProfile,
1083 kCorruptedProfileMax);
1084}
1085
Peter Qiu574996a2014-04-04 10:55:47 -07001086void Metrics::NotifyWifiAutoConnectableServices(int num_services) {
1087 SendToUMA(kMetricWifiAutoConnectableServices,
1088 num_services,
1089 kMetricWifiAutoConnectableServicesMin,
1090 kMetricWifiAutoConnectableServicesMax,
1091 kMetricWifiAutoConnectableServicesNumBuckets);
1092}
1093
1094void Metrics::NotifyWifiAvailableBSSes(int num_bss) {
1095 SendToUMA(kMetricWifiAvailableBSSes,
1096 num_bss,
1097 kMetricWifiAvailableBSSesMin,
1098 kMetricWifiAvailableBSSesMax,
1099 kMetricWifiAvailableBSSesNumBuckets);
1100}
1101
Peter Qiu39d4af02014-04-14 12:24:01 -07001102void Metrics::NotifyServicesOnSameNetwork(int num_services) {
1103 SendToUMA(kMetricServicesOnSameNetwork,
1104 num_services,
1105 kMetricServicesOnSameNetworkMin,
1106 kMetricServicesOnSameNetworkMax,
1107 kMetricServicesOnSameNetworkNumBuckets);
1108}
1109
Peter Qiue783f1c2014-05-02 11:42:33 -07001110void Metrics::NotifyUserInitiatedEvent(int event) {
1111 SendEnumToUMA(kMetricUserInitiatedEvents,
1112 event,
1113 kUserInitiatedEventMax);
1114}
1115
Peter Qiu8e430582014-04-30 14:12:37 -07001116void Metrics::NotifyWifiTxBitrate(int bitrate) {
1117 SendToUMA(kMetricWifiTxBitrate,
1118 bitrate,
1119 kMetricWifiTxBitrateMin,
1120 kMetricWifiTxBitrateMax,
1121 kMetricWifiTxBitrateNumBuckets);
1122}
1123
Peter Qiudc4e0992014-05-01 10:02:52 -07001124void Metrics::NotifyUserInitiatedConnectionResult(const string &name,
1125 int result) {
1126 SendEnumToUMA(name,
1127 result,
1128 kUserInitiatedConnectionResultMax);
1129}
1130
Peter Qiud87179e2014-07-10 18:29:22 -07001131void Metrics::NotifyUserInitiatedConnectionFailureReason(
1132 const string &name, const Service::ConnectFailure failure) {
1133 UserInitiatedConnectionFailureReason reason;
1134 switch (failure) {
1135 case Service::kFailureBadPassphrase:
1136 reason = kUserInitiatedConnectionFailureReasonBadPassphrase;
1137 break;
1138 case Service::kFailureBadWEPKey:
1139 reason = kUserInitiatedConnectionFailureReasonBadWEPKey;
1140 break;
1141 case Service::kFailureConnect:
1142 reason = kUserInitiatedConnectionFailureReasonConnect;
1143 break;
1144 case Service::kFailureDHCP:
1145 reason = kUserInitiatedConnectionFailureReasonDHCP;
1146 break;
1147 case Service::kFailureDNSLookup:
1148 reason = kUserInitiatedConnectionFailureReasonDNSLookup;
1149 break;
1150 case Service::kFailureEAPAuthentication:
1151 reason = kUserInitiatedConnectionFailureReasonEAPAuthentication;
1152 break;
1153 case Service::kFailureEAPLocalTLS:
1154 reason = kUserInitiatedConnectionFailureReasonEAPLocalTLS;
1155 break;
1156 case Service::kFailureEAPRemoteTLS:
1157 reason = kUserInitiatedConnectionFailureReasonEAPRemoteTLS;
1158 break;
1159 case Service::kFailureOutOfRange:
1160 reason = kUserInitiatedConnectionFailureReasonOutOfRange;
1161 break;
1162 case Service::kFailurePinMissing:
1163 reason = kUserInitiatedConnectionFailureReasonPinMissing;
1164 break;
1165 default:
1166 reason = kUserInitiatedConnectionFailureReasonUnknown;
1167 break;
1168 }
1169 SendEnumToUMA(name,
1170 reason,
1171 kUserInitiatedConnectionFailureReasonMax);
1172}
1173
Peter Qiuf18e7712014-05-20 09:59:46 -07001174void Metrics::NotifyFallbackDNSTestResult(Technology::Identifier technology_id,
1175 int result) {
1176 string histogram = GetFullMetricName(kMetricFallbackDNSTestResultSuffix,
1177 technology_id);
1178 SendEnumToUMA(histogram,
Peter Qiub9256f32014-05-09 15:27:29 -07001179 result,
Peter Qiuf18e7712014-05-20 09:59:46 -07001180 kFallbackDNSTestResultMax);
Peter Qiub9256f32014-05-09 15:27:29 -07001181}
1182
Peter Qiudc335f82014-05-15 10:33:17 -07001183void Metrics::NotifyNetworkProblemDetected(Technology::Identifier technology_id,
1184 int reason) {
1185 string histogram = GetFullMetricName(kMetricNetworkProblemDetectedSuffix,
1186 technology_id);
1187 SendEnumToUMA(histogram,
1188 reason,
1189 kNetworkProblemMax);
1190}
1191
Peter Qiu700de642014-07-14 16:31:30 -07001192void Metrics::NotifyDeviceConnectionStatus(ConnectionStatus status) {
1193 SendEnumToUMA(kMetricDeviceConnectionStatus, status, kConnectionStatusMax);
1194}
1195
Paul Stewart3bdf1ab2014-07-17 19:22:26 -07001196void Metrics::NotifyDhcpClientStatus(DhcpClientStatus status) {
1197 SendEnumToUMA(kMetricDhcpClientStatus, status, kDhcpClientStatusMax);
1198}
1199
Thieu Le48e6d6d2011-12-06 00:40:27 +00001200bool Metrics::SendEnumToUMA(const string &name, int sample, int max) {
mukesh agrawal94cde582013-08-12 17:55:33 -07001201 SLOG(Metrics, 5)
1202 << "Sending enum " << name << " with value " << sample << ".";
Thieu Le48e6d6d2011-12-06 00:40:27 +00001203 return library_->SendEnumToUMA(name, sample, max);
1204}
1205
Thieu Lea20cbc22012-01-09 22:01:43 +00001206bool Metrics::SendToUMA(const string &name, int sample, int min, int max,
1207 int num_buckets) {
mukesh agrawal94cde582013-08-12 17:55:33 -07001208 SLOG(Metrics, 5)
1209 << "Sending metric " << name << " with value " << sample << ".";
Thieu Lea20cbc22012-01-09 22:01:43 +00001210 return library_->SendToUMA(name, sample, min, max, num_buckets);
1211}
1212
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001213void Metrics::InitializeCommonServiceMetrics(const Service &service) {
1214 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -07001215 string histogram = GetFullMetricName(kMetricTimeToConfigMillisecondsSuffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001216 technology);
1217 AddServiceStateTransitionTimer(
1218 service,
1219 histogram,
1220 Service::kStateConfiguring,
Paul Stewart20088d82012-02-16 06:58:55 -08001221 Service::kStateConnected);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001222 histogram = GetFullMetricName(kMetricTimeToPortalMillisecondsSuffix,
1223 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001224 AddServiceStateTransitionTimer(
1225 service,
1226 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001227 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001228 Service::kStatePortal);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001229 histogram = GetFullMetricName(kMetricTimeToOnlineMillisecondsSuffix,
1230 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001231 AddServiceStateTransitionTimer(
1232 service,
1233 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001234 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001235 Service::kStateOnline);
1236}
1237
1238void Metrics::UpdateServiceStateTransitionMetrics(
1239 ServiceMetrics *service_metrics,
1240 Service::ConnectState new_state) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001241 const char *state_string = Service::ConnectStateToString(new_state);
1242 SLOG(Metrics, 5) << __func__ << ": new_state=" << state_string;
Thieu Le48e6d6d2011-12-06 00:40:27 +00001243 TimerReportersList &start_timers = service_metrics->start_on_state[new_state];
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001244 for (auto &start_timer : start_timers) {
1245 SLOG(Metrics, 5) << "Starting timer for " << start_timer->histogram_name()
1246 << " due to new state " << state_string << ".";
1247 start_timer->Start();
1248 }
Thieu Le48e6d6d2011-12-06 00:40:27 +00001249
1250 TimerReportersList &stop_timers = service_metrics->stop_on_state[new_state];
Wade Guthriee71aa492013-09-23 13:44:19 -07001251 for (auto &stop_timer : stop_timers) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001252 SLOG(Metrics, 5) << "Stopping timer for " << stop_timer->histogram_name()
1253 << " due to new state " << state_string << ".";
1254 if (stop_timer->Stop())
1255 stop_timer->ReportMilliseconds();
Thieu Le48e6d6d2011-12-06 00:40:27 +00001256 }
1257}
1258
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001259void Metrics::SendServiceFailure(const Service &service) {
Thieu Le48e6d6d2011-12-06 00:40:27 +00001260 library_->SendEnumToUMA(kMetricNetworkServiceErrors,
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001261 service.failure(),
Thieu Le48e6d6d2011-12-06 00:40:27 +00001262 kMetricNetworkServiceErrorsMax);
1263}
1264
Thieu Le9abd6742013-01-23 23:35:37 -08001265Metrics::DeviceMetrics *Metrics::GetDeviceMetrics(int interface_index) const {
1266 DeviceMetricsLookupMap::const_iterator it =
1267 devices_metrics_.find(interface_index);
Thieu Lece4483e2013-01-23 15:12:03 -08001268 if (it == devices_metrics_.end()) {
Thieu Le9abd6742013-01-23 23:35:37 -08001269 SLOG(Metrics, 2) << __func__ << ": device " << interface_index
1270 << " not found";
Thieu Lece4483e2013-01-23 15:12:03 -08001271 return NULL;
1272 }
1273 return it->second.get();
1274}
1275
Thieu Le7cf36b02013-01-30 17:15:56 -08001276void Metrics::AutoConnectMetricsReset(DeviceMetrics *device_metrics) {
1277 device_metrics->auto_connect_tries = 0;
1278 device_metrics->auto_connect_timer->Reset();
1279}
1280
Thieu Le48e6d6d2011-12-06 00:40:27 +00001281void Metrics::set_library(MetricsLibraryInterface *library) {
1282 chromeos_metrics::TimerReporter::set_metrics_lib(library);
1283 library_ = library;
1284}
1285
1286} // namespace shill