blob: ee0af9382087df66abb0a6e017a3105572c82285 [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
Peter Qiu300769e2014-08-27 11:48:45 -0700337// static
338const char Metrics::kMetricNetworkConnectionIPTypeSuffix[] =
339 "NetworkConnectionIPType";
340
341// static
342const char Metrics::kMetricIPv6ConnectivityStatusSuffix[] =
343 "IPv6ConnectivityStatus";
344
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800345Metrics::Metrics(EventDispatcher *dispatcher)
346 : dispatcher_(dispatcher),
347 library_(&metrics_library_),
Thieu Lea20cbc22012-01-09 22:01:43 +0000348 last_default_technology_(Technology::kUnknown),
349 was_online_(false),
350 time_online_timer_(new chromeos_metrics::Timer),
Thieu Leb84ba342012-03-02 15:15:19 -0800351 time_to_drop_timer_(new chromeos_metrics::Timer),
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200352 time_resume_to_ready_timer_(new chromeos_metrics::Timer),
Arman Ugurayab22c162012-10-08 19:08:38 -0700353 time_termination_actions_timer(new chromeos_metrics::Timer),
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200354 collect_bootstats_(true) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000355 metrics_library_.Init();
356 chromeos_metrics::TimerReporter::set_metrics_lib(library_);
357}
358
359Metrics::~Metrics() {}
360
361// static
Ben Chan7fab8972014-08-10 17:14:46 -0700362Metrics::WiFiChannel Metrics::WiFiFrequencyToChannel(uint16_t frequency) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000363 WiFiChannel channel = kWiFiChannelUndef;
364 if (kWiFiFrequency2412 <= frequency && frequency <= kWiFiFrequency2472) {
365 if (((frequency - kWiFiFrequency2412) % kWiFiBandwidth5MHz) == 0)
366 channel = static_cast<WiFiChannel>(
367 kWiFiChannel2412 +
368 (frequency - kWiFiFrequency2412) / kWiFiBandwidth5MHz);
369 } else if (frequency == kWiFiFrequency2484) {
370 channel = kWiFiChannel2484;
371 } else if (kWiFiFrequency5170 <= frequency &&
372 frequency <= kWiFiFrequency5230) {
373 if ((frequency % kWiFiBandwidth20MHz) == 0)
374 channel = static_cast<WiFiChannel>(
375 kWiFiChannel5180 +
376 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
377 if ((frequency % kWiFiBandwidth20MHz) == 10)
378 channel = static_cast<WiFiChannel>(
379 kWiFiChannel5170 +
380 (frequency - kWiFiFrequency5170) / kWiFiBandwidth20MHz);
381 } else if (kWiFiFrequency5240 <= frequency &&
382 frequency <= kWiFiFrequency5320) {
383 if (((frequency - kWiFiFrequency5180) % kWiFiBandwidth20MHz) == 0)
384 channel = static_cast<WiFiChannel>(
385 kWiFiChannel5180 +
386 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
387 } else if (kWiFiFrequency5500 <= frequency &&
388 frequency <= kWiFiFrequency5700) {
389 if (((frequency - kWiFiFrequency5500) % kWiFiBandwidth20MHz) == 0)
390 channel = static_cast<WiFiChannel>(
391 kWiFiChannel5500 +
392 (frequency - kWiFiFrequency5500) / kWiFiBandwidth20MHz);
393 } else if (kWiFiFrequency5745 <= frequency &&
394 frequency <= kWiFiFrequency5825) {
395 if (((frequency - kWiFiFrequency5745) % kWiFiBandwidth20MHz) == 0)
396 channel = static_cast<WiFiChannel>(
397 kWiFiChannel5745 +
398 (frequency - kWiFiFrequency5745) / kWiFiBandwidth20MHz);
399 }
400 CHECK(kWiFiChannelUndef <= channel && channel < kWiFiChannelMax);
401
402 if (channel == kWiFiChannelUndef)
403 LOG(WARNING) << "no mapping for frequency " << frequency;
404 else
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700405 SLOG(Metrics, 3) << "mapped frequency " << frequency
406 << " to enum bucket " << channel;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000407
408 return channel;
409}
410
Thieu Lead1ec2c2012-01-05 23:39:48 +0000411// static
412Metrics::WiFiSecurity Metrics::WiFiSecurityStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700413 const string &security) {
Ben Chan923a5022013-09-20 11:23:23 -0700414 if (security == kSecurityNone) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000415 return kWiFiSecurityNone;
Ben Chan923a5022013-09-20 11:23:23 -0700416 } else if (security == kSecurityWep) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000417 return kWiFiSecurityWep;
Ben Chan923a5022013-09-20 11:23:23 -0700418 } else if (security == kSecurityWpa) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000419 return kWiFiSecurityWpa;
Ben Chan923a5022013-09-20 11:23:23 -0700420 } else if (security == kSecurityRsn) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000421 return kWiFiSecurityRsn;
Ben Chan923a5022013-09-20 11:23:23 -0700422 } else if (security == kSecurity8021x) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000423 return kWiFiSecurity8021x;
Ben Chan923a5022013-09-20 11:23:23 -0700424 } else if (security == kSecurityPsk) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000425 return kWiFiSecurityPsk;
426 } else {
427 return kWiFiSecurityUnknown;
428 }
429}
430
Thieu Le85e050b2012-03-13 15:04:38 -0700431// static
Paul Stewarte4cedde2013-07-17 08:56:44 -0700432Metrics::WiFiApMode Metrics::WiFiApModeStringToEnum(const string &ap_mode) {
Ben Chan923a5022013-09-20 11:23:23 -0700433 if (ap_mode == kModeManaged) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700434 return kWiFiApModeManaged;
Ben Chan923a5022013-09-20 11:23:23 -0700435 } else if (ap_mode == kModeAdhoc) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700436 return kWiFiApModeAdHoc;
437 } else {
438 return kWiFiApModeUnknown;
439 }
440}
441
442// static
Paul Stewart21f40962013-03-01 14:27:28 -0800443Metrics::EapOuterProtocol Metrics::EapOuterProtocolStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700444 const string &outer) {
Ben Chan923a5022013-09-20 11:23:23 -0700445 if (outer == kEapMethodPEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800446 return kEapOuterProtocolPeap;
Ben Chan923a5022013-09-20 11:23:23 -0700447 } else if (outer == kEapMethodTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800448 return kEapOuterProtocolTls;
Ben Chan923a5022013-09-20 11:23:23 -0700449 } else if (outer == kEapMethodTTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800450 return kEapOuterProtocolTtls;
Ben Chan923a5022013-09-20 11:23:23 -0700451 } else if (outer == kEapMethodLEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800452 return kEapOuterProtocolLeap;
453 } else {
454 return kEapOuterProtocolUnknown;
455 }
456}
457
458// static
459Metrics::EapInnerProtocol Metrics::EapInnerProtocolStringToEnum(
Paul Stewarte4cedde2013-07-17 08:56:44 -0700460 const string &inner) {
Paul Stewart21f40962013-03-01 14:27:28 -0800461 if (inner.empty()) {
462 return kEapInnerProtocolNone;
Ben Chan923a5022013-09-20 11:23:23 -0700463 } else if (inner == kEapPhase2AuthPEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800464 return kEapInnerProtocolPeapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700465 } else if (inner == kEapPhase2AuthPEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800466 return kEapInnerProtocolPeapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700467 } else if (inner == kEapPhase2AuthTTLSEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800468 return kEapInnerProtocolTtlsEapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700469 } else if (inner == kEapPhase2AuthTTLSEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800470 return kEapInnerProtocolTtlsEapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700471 } else if (inner == kEapPhase2AuthTTLSMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800472 return kEapInnerProtocolTtlsMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700473 } else if (inner == kEapPhase2AuthTTLSMSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800474 return kEapInnerProtocolTtlsMschap;
Ben Chan923a5022013-09-20 11:23:23 -0700475 } else if (inner == kEapPhase2AuthTTLSPAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800476 return kEapInnerProtocolTtlsPap;
Ben Chan923a5022013-09-20 11:23:23 -0700477 } else if (inner == kEapPhase2AuthTTLSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800478 return kEapInnerProtocolTtlsChap;
479 } else {
480 return kEapInnerProtocolUnknown;
481 }
482}
483
484// static
Thieu Le85e050b2012-03-13 15:04:38 -0700485Metrics::PortalResult Metrics::PortalDetectionResultToEnum(
486 const PortalDetector::Result &result) {
487 DCHECK(result.final);
488 PortalResult retval = kPortalResultUnknown;
489 // The only time we should end a successful portal detection is when we're
490 // in the Content phase. If we end with kStatusSuccess in any other phase,
491 // then this indicates that something bad has happened.
492 switch (result.phase) {
493 case PortalDetector::kPhaseDNS:
494 if (result.status == PortalDetector::kStatusFailure)
495 retval = kPortalResultDNSFailure;
496 else if (result.status == PortalDetector::kStatusTimeout)
497 retval = kPortalResultDNSTimeout;
498 else
499 LOG(DFATAL) << __func__ << ": Final result status " << result.status
500 << " is not allowed in the DNS phase";
501 break;
502
503 case PortalDetector::kPhaseConnection:
504 if (result.status == PortalDetector::kStatusFailure)
505 retval = kPortalResultConnectionFailure;
506 else if (result.status == PortalDetector::kStatusTimeout)
507 retval = kPortalResultConnectionTimeout;
508 else
509 LOG(DFATAL) << __func__ << ": Final result status " << result.status
510 << " is not allowed in the Connection phase";
511 break;
512
513 case PortalDetector::kPhaseHTTP:
514 if (result.status == PortalDetector::kStatusFailure)
515 retval = kPortalResultHTTPFailure;
516 else if (result.status == PortalDetector::kStatusTimeout)
517 retval = kPortalResultHTTPTimeout;
518 else
519 LOG(DFATAL) << __func__ << ": Final result status " << result.status
520 << " is not allowed in the HTTP phase";
521 break;
522
523 case PortalDetector::kPhaseContent:
524 if (result.status == PortalDetector::kStatusSuccess)
525 retval = kPortalResultSuccess;
526 else if (result.status == PortalDetector::kStatusFailure)
527 retval = kPortalResultContentFailure;
528 else if (result.status == PortalDetector::kStatusTimeout)
529 retval = kPortalResultContentTimeout;
530 else
531 LOG(DFATAL) << __func__ << ": Final result status " << result.status
532 << " is not allowed in the Content phase";
533 break;
534
535 case PortalDetector::kPhaseUnknown:
536 retval = kPortalResultUnknown;
537 break;
538
539 default:
540 LOG(DFATAL) << __func__ << ": Invalid phase " << result.phase;
541 break;
542 }
543
544 return retval;
545}
546
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800547void Metrics::Start() {
548 SLOG(Metrics, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800549}
550
551void Metrics::Stop() {
552 SLOG(Metrics, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800553}
554
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700555void Metrics::RegisterService(const Service &service) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700556 SLOG(Metrics, 2) << __func__;
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700557 LOG_IF(WARNING, ContainsKey(services_metrics_, &service))
558 << "Repeatedly registering " << service.unique_name();
mukesh agrawal6cfe53f2013-08-13 13:39:01 -0700559 shared_ptr<ServiceMetrics> service_metrics(new ServiceMetrics());
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700560 services_metrics_[&service] = service_metrics;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000561 InitializeCommonServiceMetrics(service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000562}
563
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700564void Metrics::DeregisterService(const Service &service) {
565 services_metrics_.erase(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000566}
567
568void Metrics::AddServiceStateTransitionTimer(
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700569 const Service &service,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000570 const string &histogram_name,
571 Service::ConnectState start_state,
572 Service::ConnectState stop_state) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -0700573 SLOG(Metrics, 2) << __func__ << ": adding " << histogram_name << " for "
574 << Service::ConnectStateToString(start_state) << " -> "
575 << Service::ConnectStateToString(stop_state);
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700576 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000577 if (it == services_metrics_.end()) {
Ben Chanfad4a0b2012-04-18 15:49:59 -0700578 SLOG(Metrics, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000579 DCHECK(false);
580 return;
581 }
582 ServiceMetrics *service_metrics = it->second.get();
583 CHECK(start_state < stop_state);
584 chromeos_metrics::TimerReporter *timer =
585 new chromeos_metrics::TimerReporter(histogram_name,
Thieu Lea20cbc22012-01-09 22:01:43 +0000586 kTimerHistogramMillisecondsMin,
587 kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000588 kTimerHistogramNumBuckets);
589 service_metrics->timers.push_back(timer); // passes ownership.
590 service_metrics->start_on_state[start_state].push_back(timer);
591 service_metrics->stop_on_state[stop_state].push_back(timer);
592}
593
Thieu Lea20cbc22012-01-09 22:01:43 +0000594void Metrics::NotifyDefaultServiceChanged(const Service *service) {
595 base::TimeDelta elapsed_seconds;
596
597 Technology::Identifier technology = (service) ? service->technology() :
598 Technology::kUnknown;
599 if (technology != last_default_technology_) {
600 if (last_default_technology_ != Technology::kUnknown) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700601 string histogram = GetFullMetricName(kMetricTimeOnlineSecondsSuffix,
Thieu Lea20cbc22012-01-09 22:01:43 +0000602 last_default_technology_);
603 time_online_timer_->GetElapsedTime(&elapsed_seconds);
604 SendToUMA(histogram,
605 elapsed_seconds.InSeconds(),
606 kMetricTimeOnlineSecondsMin,
607 kMetricTimeOnlineSecondsMax,
608 kTimerHistogramNumBuckets);
609 }
610 last_default_technology_ = technology;
611 time_online_timer_->Start();
612 }
613
Thieu Lea20cbc22012-01-09 22:01:43 +0000614 // Ignore changes that are not online/offline transitions; e.g.
615 // switching between wired and wireless. TimeToDrop measures
616 // time online regardless of how we are connected.
617 if ((service == NULL && !was_online_) || (service != NULL && was_online_))
618 return;
619
620 if (service == NULL) {
621 time_to_drop_timer_->GetElapsedTime(&elapsed_seconds);
622 SendToUMA(kMetricTimeToDropSeconds,
623 elapsed_seconds.InSeconds(),
624 kMetricTimeToDropSecondsMin,
625 kMetricTimeToDropSecondsMax,
626 kTimerHistogramNumBuckets);
627 } else {
628 time_to_drop_timer_->Start();
629 }
630
631 was_online_ = (service != NULL);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000632}
633
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700634void Metrics::NotifyServiceStateChanged(const Service &service,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000635 Service::ConnectState new_state) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700636 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000637 if (it == services_metrics_.end()) {
Ben Chanfad4a0b2012-04-18 15:49:59 -0700638 SLOG(Metrics, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000639 DCHECK(false);
640 return;
641 }
642 ServiceMetrics *service_metrics = it->second.get();
643 UpdateServiceStateTransitionMetrics(service_metrics, new_state);
644
645 if (new_state == Service::kStateFailure)
646 SendServiceFailure(service);
647
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200648 if (collect_bootstats_) {
Ben Chana0ddf462014-02-06 11:32:42 -0800649 bootstat_log(base::StringPrintf("network-%s-%s",
650 Technology::NameFromIdentifier(
651 service.technology()).c_str(),
652 service.GetStateString().c_str()).c_str());
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200653 }
654
Paul Stewart20088d82012-02-16 06:58:55 -0800655 if (new_state != Service::kStateConnected)
Thieu Le48e6d6d2011-12-06 00:40:27 +0000656 return;
657
Thieu Leb84ba342012-03-02 15:15:19 -0800658 base::TimeDelta time_resume_to_ready;
659 time_resume_to_ready_timer_->GetElapsedTime(&time_resume_to_ready);
660 time_resume_to_ready_timer_->Reset();
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700661 service.SendPostReadyStateMetrics(time_resume_to_ready.InMilliseconds());
Thieu Le48e6d6d2011-12-06 00:40:27 +0000662}
663
mukesh agrawal132e96f2014-04-24 11:49:42 -0700664string Metrics::GetFullMetricName(const char *metric_suffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000665 Technology::Identifier technology_id) {
666 string technology = Technology::NameFromIdentifier(technology_id);
667 technology[0] = base::ToUpperASCII(technology[0]);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700668 return base::StringPrintf("%s.%s.%s", kMetricPrefix, technology.c_str(),
669 metric_suffix);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000670}
671
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700672void Metrics::NotifyServiceDisconnect(const Service &service) {
673 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700674 string histogram = GetFullMetricName(kMetricDisconnectSuffix, technology);
Thieu Le67370f62012-02-14 23:01:42 +0000675 SendToUMA(histogram,
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700676 service.explicitly_disconnected(),
Thieu Le67370f62012-02-14 23:01:42 +0000677 kMetricDisconnectMin,
678 kMetricDisconnectMax,
679 kMetricDisconnectNumBuckets);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000680}
681
Wade Guthrie9ec08062013-09-25 15:22:24 -0700682void Metrics::NotifySignalAtDisconnect(const Service &service,
683 int16_t signal_strength) {
684 // Negate signal_strength (goes from dBm to -dBm) because the metrics don't
685 // seem to handle negative values well. Now everything's positive.
686 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700687 string histogram = GetFullMetricName(kMetricSignalAtDisconnectSuffix,
688 technology);
Wade Guthrie9ec08062013-09-25 15:22:24 -0700689 SendToUMA(histogram,
690 -signal_strength,
691 kMetricSignalAtDisconnectMin,
692 kMetricSignalAtDisconnectMax,
693 kMetricSignalAtDisconnectNumBuckets);
694}
695
Daniel Eratfac09532014-04-17 20:25:59 -0700696void Metrics::NotifySuspendDone() {
697 time_resume_to_ready_timer_->Start();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000698}
699
Arman Ugurayab22c162012-10-08 19:08:38 -0700700void Metrics::NotifyTerminationActionsStarted(
701 TerminationActionReason /*reason*/) {
702 if (time_termination_actions_timer->HasStarted())
703 return;
704 time_termination_actions_timer->Start();
705}
706
707void Metrics::NotifyTerminationActionsCompleted(
708 TerminationActionReason reason, bool success) {
709 if (!time_termination_actions_timer->HasStarted())
710 return;
711
712 int result = success ? kTerminationActionResultSuccess :
713 kTerminationActionResultFailure;
714
715 base::TimeDelta elapsed_time;
716 time_termination_actions_timer->GetElapsedTime(&elapsed_time);
717 time_termination_actions_timer->Reset();
718 string time_metric, result_metric;
719 switch (reason) {
720 case kTerminationActionReasonSuspend:
721 time_metric = kMetricTerminationActionTimeOnSuspend;
722 result_metric = kMetricTerminationActionResultOnSuspend;
723 break;
724 case kTerminationActionReasonTerminate:
725 time_metric = kMetricTerminationActionTimeOnTerminate;
726 result_metric = kMetricTerminationActionResultOnTerminate;
727 break;
728 }
729
730 SendToUMA(time_metric,
731 elapsed_time.InMilliseconds(),
732 kMetricTerminationActionTimeMillisecondsMin,
733 kMetricTerminationActionTimeMillisecondsMax,
734 kTimerHistogramNumBuckets);
735
736 SendEnumToUMA(result_metric,
737 result,
738 kTerminationActionResultMax);
739}
740
Paul Stewartff845fc2012-08-07 07:28:44 -0700741void Metrics::NotifyLinkMonitorFailure(
Paul Stewart0443aa52012-08-09 10:43:50 -0700742 Technology::Identifier technology,
743 LinkMonitorFailure failure,
Paul Stewartf1961f82012-09-11 20:45:39 -0700744 int seconds_to_failure,
745 int broadcast_error_count,
746 int unicast_error_count) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700747 string histogram = GetFullMetricName(kMetricLinkMonitorFailureSuffix,
Paul Stewartff845fc2012-08-07 07:28:44 -0700748 technology);
749 SendEnumToUMA(histogram, failure, kLinkMonitorFailureMax);
Paul Stewart0443aa52012-08-09 10:43:50 -0700750
751 if (failure == kLinkMonitorFailureThresholdReached) {
752 if (seconds_to_failure > kMetricLinkMonitorSecondsToFailureMax) {
753 seconds_to_failure = kMetricLinkMonitorSecondsToFailureMax;
754 }
mukesh agrawal132e96f2014-04-24 11:49:42 -0700755 histogram = GetFullMetricName(kMetricLinkMonitorSecondsToFailureSuffix,
Paul Stewart0443aa52012-08-09 10:43:50 -0700756 technology);
757 SendToUMA(histogram,
758 seconds_to_failure,
759 kMetricLinkMonitorSecondsToFailureMin,
760 kMetricLinkMonitorSecondsToFailureMax,
761 kMetricLinkMonitorSecondsToFailureNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700762 histogram = GetFullMetricName(
763 kMetricLinkMonitorBroadcastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700764 SendToUMA(histogram,
765 broadcast_error_count,
766 kMetricLinkMonitorErrorCountMin,
767 kMetricLinkMonitorErrorCountMax,
768 kMetricLinkMonitorErrorCountNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700769 histogram = GetFullMetricName(
770 kMetricLinkMonitorUnicastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700771 SendToUMA(histogram,
772 unicast_error_count,
773 kMetricLinkMonitorErrorCountMin,
774 kMetricLinkMonitorErrorCountMax,
775 kMetricLinkMonitorErrorCountNumBuckets);
776 }
Paul Stewartff845fc2012-08-07 07:28:44 -0700777}
778
779void Metrics::NotifyLinkMonitorResponseTimeSampleAdded(
780 Technology::Identifier technology,
Paul Stewartf1961f82012-09-11 20:45:39 -0700781 int response_time_milliseconds) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700782 string histogram = GetFullMetricName(
783 kMetricLinkMonitorResponseTimeSampleSuffix, technology);
Paul Stewartff845fc2012-08-07 07:28:44 -0700784 SendToUMA(histogram,
785 response_time_milliseconds,
786 kMetricLinkMonitorResponseTimeSampleMin,
787 kMetricLinkMonitorResponseTimeSampleMax,
788 kMetricLinkMonitorResponseTimeSampleNumBuckets);
789}
790
Wade Guthried4977f22012-08-22 12:37:54 -0700791void Metrics::Notify80211Disconnect(WiFiDisconnectByWhom by_whom,
792 IEEE_80211::WiFiReasonCode reason) {
793 string metric_disconnect_reason;
794 string metric_disconnect_type;
795 WiFiStatusType type;
796
797 if (by_whom == kDisconnectedByAp) {
798 metric_disconnect_reason = kMetricLinkApDisconnectReason;
799 metric_disconnect_type = kMetricLinkApDisconnectType;
800 type = kStatusCodeTypeByAp;
801 } else {
802 metric_disconnect_reason = kMetricLinkClientDisconnectReason;
803 metric_disconnect_type = kMetricLinkClientDisconnectType;
Wade Guthrie60a37062013-04-02 11:39:09 -0700804 switch (reason) {
Wade Guthried4977f22012-08-22 12:37:54 -0700805 case IEEE_80211::kReasonCodeSenderHasLeft:
806 case IEEE_80211::kReasonCodeDisassociatedHasLeft:
807 type = kStatusCodeTypeByUser;
808 break;
809
810 case IEEE_80211::kReasonCodeInactivity:
811 type = kStatusCodeTypeConsideredDead;
812 break;
813
814 default:
815 type = kStatusCodeTypeByClient;
816 break;
817 }
818 }
819 SendEnumToUMA(metric_disconnect_reason, reason,
820 IEEE_80211::kStatusCodeMax);
821 SendEnumToUMA(metric_disconnect_type, type, kStatusCodeTypeMax);
822}
823
Thieu Lec8078a62013-01-22 18:01:12 -0800824void Metrics::RegisterDevice(int interface_index,
825 Technology::Identifier technology) {
Thieu Le9abd6742013-01-23 23:35:37 -0800826 SLOG(Metrics, 2) << __func__ << ": " << interface_index;
Thieu Lec8078a62013-01-22 18:01:12 -0800827 shared_ptr<DeviceMetrics> device_metrics(new DeviceMetrics);
828 devices_metrics_[interface_index] = device_metrics;
Thieu Le9abd6742013-01-23 23:35:37 -0800829 device_metrics->technology = technology;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700830 string histogram = GetFullMetricName(
831 kMetricTimeToInitializeMillisecondsSuffix, technology);
Thieu Lec8078a62013-01-22 18:01:12 -0800832 device_metrics->initialization_timer.reset(
833 new chromeos_metrics::TimerReporter(
834 histogram,
835 kMetricTimeToInitializeMillisecondsMin,
836 kMetricTimeToInitializeMillisecondsMax,
837 kMetricTimeToInitializeMillisecondsNumBuckets));
838 device_metrics->initialization_timer->Start();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700839 histogram = GetFullMetricName(kMetricTimeToEnableMillisecondsSuffix,
Thieu Lece4483e2013-01-23 15:12:03 -0800840 technology);
841 device_metrics->enable_timer.reset(
842 new chromeos_metrics::TimerReporter(
843 histogram,
844 kMetricTimeToEnableMillisecondsMin,
845 kMetricTimeToEnableMillisecondsMax,
846 kMetricTimeToEnableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700847 histogram = GetFullMetricName(kMetricTimeToDisableMillisecondsSuffix,
Thieu Lea2519bf2013-01-23 16:51:54 -0800848 technology);
849 device_metrics->disable_timer.reset(
850 new chromeos_metrics::TimerReporter(
851 histogram,
852 kMetricTimeToDisableMillisecondsMin,
853 kMetricTimeToDisableMillisecondsMax,
854 kMetricTimeToDisableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700855 histogram = GetFullMetricName(kMetricTimeToScanMillisecondsSuffix,
Thieu Le18c11072013-01-28 17:21:37 -0800856 technology);
857 device_metrics->scan_timer.reset(
858 new chromeos_metrics::TimerReporter(
859 histogram,
860 kMetricTimeToScanMillisecondsMin,
861 kMetricTimeToScanMillisecondsMax,
862 kMetricTimeToScanMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700863 histogram = GetFullMetricName(kMetricTimeToConnectMillisecondsSuffix,
Thieu Lecdb5a212013-01-25 11:17:18 -0800864 technology);
865 device_metrics->connect_timer.reset(
866 new chromeos_metrics::TimerReporter(
867 histogram,
868 kMetricTimeToConnectMillisecondsMin,
869 kMetricTimeToConnectMillisecondsMax,
870 kMetricTimeToConnectMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -0700871 histogram = GetFullMetricName(kMetricTimeToScanAndConnectMillisecondsSuffix,
Wade Guthrie44f290d2013-05-28 10:16:25 -0700872 technology);
873 device_metrics->scan_connect_timer.reset(
874 new chromeos_metrics::TimerReporter(
875 histogram,
876 kMetricTimeToScanMillisecondsMin,
877 kMetricTimeToScanMillisecondsMax +
878 kMetricTimeToConnectMillisecondsMax,
879 kMetricTimeToScanMillisecondsNumBuckets +
880 kMetricTimeToConnectMillisecondsNumBuckets));
Thieu Le7cf36b02013-01-30 17:15:56 -0800881 device_metrics->auto_connect_timer.reset(
882 new chromeos_metrics::TimerReporter(
883 kMetricCellularAutoConnectTotalTime,
884 kMetricCellularAutoConnectTotalTimeMin,
885 kMetricCellularAutoConnectTotalTimeMax,
886 kMetricCellularAutoConnectTotalTimeNumBuckets));
Thieu Lec8078a62013-01-22 18:01:12 -0800887}
888
Thieu Le9abd6742013-01-23 23:35:37 -0800889bool Metrics::IsDeviceRegistered(int interface_index,
890 Technology::Identifier technology) {
891 SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index
892 << ", technology: " << technology;
893 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
894 if (device_metrics == NULL)
895 return false;
896 // Make sure the device technologies match.
897 return (technology == device_metrics->technology);
898}
899
Thieu Lec8078a62013-01-22 18:01:12 -0800900void Metrics::DeregisterDevice(int interface_index) {
Thieu Le9abd6742013-01-23 23:35:37 -0800901 SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index;
Thieu Lec8078a62013-01-22 18:01:12 -0800902 devices_metrics_.erase(interface_index);
903}
904
905void Metrics::NotifyDeviceInitialized(int interface_index) {
Thieu Lece4483e2013-01-23 15:12:03 -0800906 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
907 if (device_metrics == NULL)
Thieu Lec8078a62013-01-22 18:01:12 -0800908 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700909 if (!device_metrics->initialization_timer->Stop())
910 return;
Thieu Lec8078a62013-01-22 18:01:12 -0800911 device_metrics->initialization_timer->ReportMilliseconds();
912}
913
Thieu Lece4483e2013-01-23 15:12:03 -0800914void Metrics::NotifyDeviceEnableStarted(int interface_index) {
915 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
916 if (device_metrics == NULL)
917 return;
918 device_metrics->enable_timer->Start();
919}
920
921void Metrics::NotifyDeviceEnableFinished(int interface_index) {
922 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
923 if (device_metrics == NULL)
924 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700925 if (!device_metrics->enable_timer->Stop())
926 return;
Thieu Lece4483e2013-01-23 15:12:03 -0800927 device_metrics->enable_timer->ReportMilliseconds();
928}
929
Thieu Lea2519bf2013-01-23 16:51:54 -0800930void Metrics::NotifyDeviceDisableStarted(int interface_index) {
931 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
932 if (device_metrics == NULL)
933 return;
934 device_metrics->disable_timer->Start();
935}
936
937void Metrics::NotifyDeviceDisableFinished(int interface_index) {
938 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
939 if (device_metrics == NULL)
940 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700941 if (!device_metrics->disable_timer->Stop())
942 return;
Thieu Lea2519bf2013-01-23 16:51:54 -0800943 device_metrics->disable_timer->ReportMilliseconds();
944}
945
Thieu Le18c11072013-01-28 17:21:37 -0800946void Metrics::NotifyDeviceScanStarted(int interface_index) {
947 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
948 if (device_metrics == NULL)
949 return;
Thieu Le18c11072013-01-28 17:21:37 -0800950 device_metrics->scan_timer->Start();
Wade Guthrie44f290d2013-05-28 10:16:25 -0700951 device_metrics->scan_connect_timer->Start();
Thieu Le18c11072013-01-28 17:21:37 -0800952}
953
954void Metrics::NotifyDeviceScanFinished(int interface_index) {
955 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
956 if (device_metrics == NULL)
957 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700958 if (!device_metrics->scan_timer->Stop())
959 return;
Wade Guthrie68d41092013-04-02 12:56:02 -0700960 // Don't send TimeToScan metrics if the elapsed time exceeds the max metrics
961 // value. Huge scan times usually mean something's gone awry; for cellular,
962 // for instance, this usually means that the modem is in an area without
963 // service and we're not interested in this scenario.
Thieu Le18c11072013-01-28 17:21:37 -0800964 base::TimeDelta elapsed_time;
965 device_metrics->scan_timer->GetElapsedTime(&elapsed_time);
966 if (elapsed_time.InMilliseconds() <= kMetricTimeToScanMillisecondsMax)
967 device_metrics->scan_timer->ReportMilliseconds();
968}
969
Wade Guthrie44f290d2013-05-28 10:16:25 -0700970void Metrics::ResetScanTimer(int interface_index) {
971 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
972 if (device_metrics == NULL)
973 return;
974 device_metrics->scan_timer->Reset();
975}
976
Thieu Le7cf36b02013-01-30 17:15:56 -0800977void Metrics::NotifyDeviceConnectStarted(int interface_index,
978 bool is_auto_connecting) {
Thieu Lecdb5a212013-01-25 11:17:18 -0800979 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
980 if (device_metrics == NULL)
981 return;
982 device_metrics->connect_timer->Start();
Thieu Le7cf36b02013-01-30 17:15:56 -0800983
984 if (is_auto_connecting) {
985 device_metrics->auto_connect_tries++;
986 if (device_metrics->auto_connect_tries == 1)
987 device_metrics->auto_connect_timer->Start();
988 } else {
989 AutoConnectMetricsReset(device_metrics);
990 }
Thieu Lecdb5a212013-01-25 11:17:18 -0800991}
992
993void Metrics::NotifyDeviceConnectFinished(int interface_index) {
994 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
995 if (device_metrics == NULL)
996 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -0700997 if (!device_metrics->connect_timer->Stop())
998 return;
Thieu Lecdb5a212013-01-25 11:17:18 -0800999 device_metrics->connect_timer->ReportMilliseconds();
Thieu Le7cf36b02013-01-30 17:15:56 -08001000
1001 if (device_metrics->auto_connect_tries > 0) {
Wade Guthrie091c41c2013-03-22 15:48:53 -07001002 if (!device_metrics->auto_connect_timer->Stop())
1003 return;
Thieu Le7cf36b02013-01-30 17:15:56 -08001004 base::TimeDelta elapsed_time;
1005 device_metrics->auto_connect_timer->GetElapsedTime(&elapsed_time);
1006 if (elapsed_time.InMilliseconds() > kMetricCellularAutoConnectTotalTimeMax)
1007 return;
1008 device_metrics->auto_connect_timer->ReportMilliseconds();
1009 SendToUMA(kMetricCellularAutoConnectTries,
1010 device_metrics->auto_connect_tries,
1011 kMetricCellularAutoConnectTriesMin,
1012 kMetricCellularAutoConnectTriesMax,
1013 kMetricCellularAutoConnectTriesNumBuckets);
1014 AutoConnectMetricsReset(device_metrics);
1015 }
Wade Guthrie44f290d2013-05-28 10:16:25 -07001016
1017 if (!device_metrics->scan_connect_timer->Stop())
1018 return;
Wade Guthrie44f290d2013-05-28 10:16:25 -07001019 device_metrics->scan_connect_timer->ReportMilliseconds();
1020}
1021
1022void Metrics::ResetConnectTimer(int interface_index) {
1023 DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
1024 if (device_metrics == NULL)
1025 return;
1026 device_metrics->connect_timer->Reset();
1027 device_metrics->scan_connect_timer->Reset();
Thieu Lecdb5a212013-01-25 11:17:18 -08001028}
1029
Prathmesh Prabhu08757aa2013-05-15 17:17:33 -07001030void Metrics::Notify3GPPRegistrationDelayedDropPosted() {
1031 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1032 kCellular3GPPRegistrationDelayedDropPosted,
1033 kCellular3GPPRegistrationDelayedDropMax);
1034}
1035
1036void Metrics::Notify3GPPRegistrationDelayedDropCanceled() {
1037 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1038 kCellular3GPPRegistrationDelayedDropCanceled,
1039 kCellular3GPPRegistrationDelayedDropMax);
1040}
1041
mukesh agrawal09e08112013-08-16 13:26:44 -07001042void Metrics::NotifyCellularDeviceDrop(const string &network_technology,
Ben Chan7fab8972014-08-10 17:14:46 -07001043 uint16_t signal_strength) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001044 SLOG(Metrics, 2) << __func__ << ": " << network_technology
1045 << ", " << signal_strength;
1046 CellularDropTechnology drop_technology = kCellularDropTechnologyUnknown;
Ben Chan923a5022013-09-20 11:23:23 -07001047 if (network_technology == kNetworkTechnology1Xrtt) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001048 drop_technology = kCellularDropTechnology1Xrtt;
Ben Chan923a5022013-09-20 11:23:23 -07001049 } else if (network_technology == kNetworkTechnologyEdge) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001050 drop_technology = kCellularDropTechnologyEdge;
Ben Chan923a5022013-09-20 11:23:23 -07001051 } else if (network_technology == kNetworkTechnologyEvdo) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001052 drop_technology = kCellularDropTechnologyEvdo;
Ben Chan923a5022013-09-20 11:23:23 -07001053 } else if (network_technology == kNetworkTechnologyGprs) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001054 drop_technology = kCellularDropTechnologyGprs;
Ben Chan923a5022013-09-20 11:23:23 -07001055 } else if (network_technology == kNetworkTechnologyGsm) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001056 drop_technology = kCellularDropTechnologyGsm;
Ben Chan923a5022013-09-20 11:23:23 -07001057 } else if (network_technology == kNetworkTechnologyHspa) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001058 drop_technology = kCellularDropTechnologyHspa;
Ben Chan923a5022013-09-20 11:23:23 -07001059 } else if (network_technology == kNetworkTechnologyHspaPlus) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001060 drop_technology = kCellularDropTechnologyHspaPlus;
Ben Chan923a5022013-09-20 11:23:23 -07001061 } else if (network_technology == kNetworkTechnologyLte) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001062 drop_technology = kCellularDropTechnologyLte;
Ben Chan923a5022013-09-20 11:23:23 -07001063 } else if (network_technology == kNetworkTechnologyUmts) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001064 drop_technology = kCellularDropTechnologyUmts;
1065 }
1066 SendEnumToUMA(kMetricCellularDrop,
1067 drop_technology,
1068 kCellularDropTechnologyMax);
1069 SendToUMA(kMetricCellularSignalStrengthBeforeDrop,
1070 signal_strength,
1071 kMetricCellularSignalStrengthBeforeDropMin,
1072 kMetricCellularSignalStrengthBeforeDropMax,
1073 kMetricCellularSignalStrengthBeforeDropNumBuckets);
1074}
1075
Thieu Leb7aa5f72013-01-31 15:57:48 -08001076void Metrics::NotifyCellularDeviceFailure(const Error &error) {
1077 library_->SendUserActionToUMA(
1078 kMetricCellularFailureReason + error.message());
1079}
1080
Thieu Le91fccf62013-04-22 15:23:16 -07001081void Metrics::NotifyCellularOutOfCredits(
1082 Metrics::CellularOutOfCreditsReason reason) {
1083 SendEnumToUMA(kMetricCellularOutOfCreditsReason,
1084 reason,
1085 kCellularOutOfCreditsReasonMax);
1086}
1087
Thieu Le5133b712013-02-19 14:47:21 -08001088void Metrics::NotifyCorruptedProfile() {
1089 SendEnumToUMA(kMetricCorruptedProfile,
1090 kCorruptedProfile,
1091 kCorruptedProfileMax);
1092}
1093
Peter Qiu574996a2014-04-04 10:55:47 -07001094void Metrics::NotifyWifiAutoConnectableServices(int num_services) {
1095 SendToUMA(kMetricWifiAutoConnectableServices,
1096 num_services,
1097 kMetricWifiAutoConnectableServicesMin,
1098 kMetricWifiAutoConnectableServicesMax,
1099 kMetricWifiAutoConnectableServicesNumBuckets);
1100}
1101
1102void Metrics::NotifyWifiAvailableBSSes(int num_bss) {
1103 SendToUMA(kMetricWifiAvailableBSSes,
1104 num_bss,
1105 kMetricWifiAvailableBSSesMin,
1106 kMetricWifiAvailableBSSesMax,
1107 kMetricWifiAvailableBSSesNumBuckets);
1108}
1109
Peter Qiu39d4af02014-04-14 12:24:01 -07001110void Metrics::NotifyServicesOnSameNetwork(int num_services) {
1111 SendToUMA(kMetricServicesOnSameNetwork,
1112 num_services,
1113 kMetricServicesOnSameNetworkMin,
1114 kMetricServicesOnSameNetworkMax,
1115 kMetricServicesOnSameNetworkNumBuckets);
1116}
1117
Peter Qiue783f1c2014-05-02 11:42:33 -07001118void Metrics::NotifyUserInitiatedEvent(int event) {
1119 SendEnumToUMA(kMetricUserInitiatedEvents,
1120 event,
1121 kUserInitiatedEventMax);
1122}
1123
Peter Qiu8e430582014-04-30 14:12:37 -07001124void Metrics::NotifyWifiTxBitrate(int bitrate) {
1125 SendToUMA(kMetricWifiTxBitrate,
1126 bitrate,
1127 kMetricWifiTxBitrateMin,
1128 kMetricWifiTxBitrateMax,
1129 kMetricWifiTxBitrateNumBuckets);
1130}
1131
Peter Qiudc4e0992014-05-01 10:02:52 -07001132void Metrics::NotifyUserInitiatedConnectionResult(const string &name,
1133 int result) {
1134 SendEnumToUMA(name,
1135 result,
1136 kUserInitiatedConnectionResultMax);
1137}
1138
Peter Qiud87179e2014-07-10 18:29:22 -07001139void Metrics::NotifyUserInitiatedConnectionFailureReason(
1140 const string &name, const Service::ConnectFailure failure) {
1141 UserInitiatedConnectionFailureReason reason;
1142 switch (failure) {
1143 case Service::kFailureBadPassphrase:
1144 reason = kUserInitiatedConnectionFailureReasonBadPassphrase;
1145 break;
1146 case Service::kFailureBadWEPKey:
1147 reason = kUserInitiatedConnectionFailureReasonBadWEPKey;
1148 break;
1149 case Service::kFailureConnect:
1150 reason = kUserInitiatedConnectionFailureReasonConnect;
1151 break;
1152 case Service::kFailureDHCP:
1153 reason = kUserInitiatedConnectionFailureReasonDHCP;
1154 break;
1155 case Service::kFailureDNSLookup:
1156 reason = kUserInitiatedConnectionFailureReasonDNSLookup;
1157 break;
1158 case Service::kFailureEAPAuthentication:
1159 reason = kUserInitiatedConnectionFailureReasonEAPAuthentication;
1160 break;
1161 case Service::kFailureEAPLocalTLS:
1162 reason = kUserInitiatedConnectionFailureReasonEAPLocalTLS;
1163 break;
1164 case Service::kFailureEAPRemoteTLS:
1165 reason = kUserInitiatedConnectionFailureReasonEAPRemoteTLS;
1166 break;
1167 case Service::kFailureOutOfRange:
1168 reason = kUserInitiatedConnectionFailureReasonOutOfRange;
1169 break;
1170 case Service::kFailurePinMissing:
1171 reason = kUserInitiatedConnectionFailureReasonPinMissing;
1172 break;
1173 default:
1174 reason = kUserInitiatedConnectionFailureReasonUnknown;
1175 break;
1176 }
1177 SendEnumToUMA(name,
1178 reason,
1179 kUserInitiatedConnectionFailureReasonMax);
1180}
1181
Peter Qiuf18e7712014-05-20 09:59:46 -07001182void Metrics::NotifyFallbackDNSTestResult(Technology::Identifier technology_id,
1183 int result) {
1184 string histogram = GetFullMetricName(kMetricFallbackDNSTestResultSuffix,
1185 technology_id);
1186 SendEnumToUMA(histogram,
Peter Qiub9256f32014-05-09 15:27:29 -07001187 result,
Peter Qiuf18e7712014-05-20 09:59:46 -07001188 kFallbackDNSTestResultMax);
Peter Qiub9256f32014-05-09 15:27:29 -07001189}
1190
Peter Qiudc335f82014-05-15 10:33:17 -07001191void Metrics::NotifyNetworkProblemDetected(Technology::Identifier technology_id,
1192 int reason) {
1193 string histogram = GetFullMetricName(kMetricNetworkProblemDetectedSuffix,
1194 technology_id);
1195 SendEnumToUMA(histogram,
1196 reason,
1197 kNetworkProblemMax);
1198}
1199
Peter Qiu700de642014-07-14 16:31:30 -07001200void Metrics::NotifyDeviceConnectionStatus(ConnectionStatus status) {
1201 SendEnumToUMA(kMetricDeviceConnectionStatus, status, kConnectionStatusMax);
1202}
1203
Paul Stewart3bdf1ab2014-07-17 19:22:26 -07001204void Metrics::NotifyDhcpClientStatus(DhcpClientStatus status) {
1205 SendEnumToUMA(kMetricDhcpClientStatus, status, kDhcpClientStatusMax);
1206}
1207
Peter Qiu300769e2014-08-27 11:48:45 -07001208void Metrics::NotifyNetworkConnectionIPType(
1209 Technology::Identifier technology_id, NetworkConnectionIPType type) {
1210 string histogram = GetFullMetricName(kMetricNetworkConnectionIPTypeSuffix,
1211 technology_id);
1212 SendEnumToUMA(histogram, type, kNetworkConnectionIPTypeMax);
1213}
1214
1215void Metrics::NotifyIPv6ConnectivityStatus(Technology::Identifier technology_id,
1216 bool status) {
1217 string histogram = GetFullMetricName(kMetricIPv6ConnectivityStatusSuffix,
1218 technology_id);
1219 IPv6ConnectivityStatus ipv6_status = status ? kIPv6ConnectivityStatusYes
1220 : kIPv6ConnectivityStatusNo;
1221 SendEnumToUMA(histogram, ipv6_status, kIPv6ConnectivityStatusMax);
1222}
1223
Thieu Le48e6d6d2011-12-06 00:40:27 +00001224bool Metrics::SendEnumToUMA(const string &name, int sample, int max) {
mukesh agrawal94cde582013-08-12 17:55:33 -07001225 SLOG(Metrics, 5)
1226 << "Sending enum " << name << " with value " << sample << ".";
Thieu Le48e6d6d2011-12-06 00:40:27 +00001227 return library_->SendEnumToUMA(name, sample, max);
1228}
1229
Thieu Lea20cbc22012-01-09 22:01:43 +00001230bool Metrics::SendToUMA(const string &name, int sample, int min, int max,
1231 int num_buckets) {
mukesh agrawal94cde582013-08-12 17:55:33 -07001232 SLOG(Metrics, 5)
1233 << "Sending metric " << name << " with value " << sample << ".";
Thieu Lea20cbc22012-01-09 22:01:43 +00001234 return library_->SendToUMA(name, sample, min, max, num_buckets);
1235}
1236
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001237void Metrics::InitializeCommonServiceMetrics(const Service &service) {
1238 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -07001239 string histogram = GetFullMetricName(kMetricTimeToConfigMillisecondsSuffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001240 technology);
1241 AddServiceStateTransitionTimer(
1242 service,
1243 histogram,
1244 Service::kStateConfiguring,
Paul Stewart20088d82012-02-16 06:58:55 -08001245 Service::kStateConnected);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001246 histogram = GetFullMetricName(kMetricTimeToPortalMillisecondsSuffix,
1247 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001248 AddServiceStateTransitionTimer(
1249 service,
1250 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001251 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001252 Service::kStatePortal);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001253 histogram = GetFullMetricName(kMetricTimeToOnlineMillisecondsSuffix,
1254 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001255 AddServiceStateTransitionTimer(
1256 service,
1257 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001258 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001259 Service::kStateOnline);
1260}
1261
1262void Metrics::UpdateServiceStateTransitionMetrics(
1263 ServiceMetrics *service_metrics,
1264 Service::ConnectState new_state) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001265 const char *state_string = Service::ConnectStateToString(new_state);
1266 SLOG(Metrics, 5) << __func__ << ": new_state=" << state_string;
Thieu Le48e6d6d2011-12-06 00:40:27 +00001267 TimerReportersList &start_timers = service_metrics->start_on_state[new_state];
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001268 for (auto &start_timer : start_timers) {
1269 SLOG(Metrics, 5) << "Starting timer for " << start_timer->histogram_name()
1270 << " due to new state " << state_string << ".";
1271 start_timer->Start();
1272 }
Thieu Le48e6d6d2011-12-06 00:40:27 +00001273
1274 TimerReportersList &stop_timers = service_metrics->stop_on_state[new_state];
Wade Guthriee71aa492013-09-23 13:44:19 -07001275 for (auto &stop_timer : stop_timers) {
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001276 SLOG(Metrics, 5) << "Stopping timer for " << stop_timer->histogram_name()
1277 << " due to new state " << state_string << ".";
1278 if (stop_timer->Stop())
1279 stop_timer->ReportMilliseconds();
Thieu Le48e6d6d2011-12-06 00:40:27 +00001280 }
1281}
1282
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001283void Metrics::SendServiceFailure(const Service &service) {
Thieu Le48e6d6d2011-12-06 00:40:27 +00001284 library_->SendEnumToUMA(kMetricNetworkServiceErrors,
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001285 service.failure(),
Thieu Le48e6d6d2011-12-06 00:40:27 +00001286 kMetricNetworkServiceErrorsMax);
1287}
1288
Thieu Le9abd6742013-01-23 23:35:37 -08001289Metrics::DeviceMetrics *Metrics::GetDeviceMetrics(int interface_index) const {
1290 DeviceMetricsLookupMap::const_iterator it =
1291 devices_metrics_.find(interface_index);
Thieu Lece4483e2013-01-23 15:12:03 -08001292 if (it == devices_metrics_.end()) {
Thieu Le9abd6742013-01-23 23:35:37 -08001293 SLOG(Metrics, 2) << __func__ << ": device " << interface_index
1294 << " not found";
Thieu Lece4483e2013-01-23 15:12:03 -08001295 return NULL;
1296 }
1297 return it->second.get();
1298}
1299
Thieu Le7cf36b02013-01-30 17:15:56 -08001300void Metrics::AutoConnectMetricsReset(DeviceMetrics *device_metrics) {
1301 device_metrics->auto_connect_tries = 0;
1302 device_metrics->auto_connect_timer->Reset();
1303}
1304
Thieu Le48e6d6d2011-12-06 00:40:27 +00001305void Metrics::set_library(MetricsLibraryInterface *library) {
1306 chromeos_metrics::TimerReporter::set_metrics_lib(library);
1307 library_ = library;
1308}
1309
1310} // namespace shill