blob: a6b0b3d6e7965dd64abe5cf00e2d746ceb825b33 [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
Paul Stewartff845fc2012-08-07 07:28:44 -070012#include "shill/link_monitor.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070013#include "shill/logging.h"
Thieu Le48e6d6d2011-12-06 00:40:27 +000014
15using std::string;
Alex Vakulenko8a532292014-06-16 17:18:44 -070016using std::shared_ptr;
Thieu Le48e6d6d2011-12-06 00:40:27 +000017
18namespace shill {
19
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070020namespace Logging {
21static auto kModuleLogScope = ScopeLogger::kMetrics;
Paul Stewart8ae18742015-06-16 13:13:10 -070022static string ObjectID(const Metrics* m) { return "(metrics)"; }
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070023}
24
mukesh agrawal132e96f2014-04-24 11:49:42 -070025static const char kMetricPrefix[] = "Network.Shill";
26
Thieu Le48e6d6d2011-12-06 00:40:27 +000027// static
Thieu Lec31e6f92012-08-03 13:08:58 -070028// Our disconnect enumeration values are 0 (System Disconnect) and
29// 1 (User Disconnect), see histograms.xml, but Chrome needs a minimum
30// enum value of 1 and the minimum number of buckets needs to be 3 (see
31// histogram.h). Instead of remapping System Disconnect to 1 and
32// User Disconnect to 2, we can just leave the enumerated values as-is
33// because Chrome implicitly creates a [0-1) bucket for us. Using Min=1,
34// Max=2 and NumBuckets=3 gives us the following three buckets:
35// [0-1), [1-2), [2-INT_MAX). We end up with an extra bucket [2-INT_MAX)
36// that we can safely ignore.
mukesh agrawal132e96f2014-04-24 11:49:42 -070037const char Metrics::kMetricDisconnectSuffix[] = "Disconnect";
Thieu Lec31e6f92012-08-03 13:08:58 -070038const int Metrics::kMetricDisconnectMax = 2;
39const int Metrics::kMetricDisconnectMin = 1;
40const int Metrics::kMetricDisconnectNumBuckets = 3;
Thieu Le67370f62012-02-14 23:01:42 +000041
mukesh agrawal132e96f2014-04-24 11:49:42 -070042const char Metrics::kMetricSignalAtDisconnectSuffix[] = "SignalAtDisconnect";
Wade Guthrie9ec08062013-09-25 15:22:24 -070043const int Metrics::kMetricSignalAtDisconnectMin = 0;
44const int Metrics::kMetricSignalAtDisconnectMax = 200;
45const int Metrics::kMetricSignalAtDisconnectNumBuckets = 40;
46
mukesh agrawal132e96f2014-04-24 11:49:42 -070047const char Metrics::kMetricNetworkApModeSuffix[] = "ApMode";
48const char Metrics::kMetricNetworkChannelSuffix[] = "Channel";
Thieu Le48e6d6d2011-12-06 00:40:27 +000049const int Metrics::kMetricNetworkChannelMax = Metrics::kWiFiChannelMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070050const char Metrics::kMetricNetworkEapInnerProtocolSuffix[] = "EapInnerProtocol";
Paul Stewart21f40962013-03-01 14:27:28 -080051const int Metrics::kMetricNetworkEapInnerProtocolMax =
52 Metrics::kEapInnerProtocolMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070053const char Metrics::kMetricNetworkEapOuterProtocolSuffix[] = "EapOuterProtocol";
Paul Stewart21f40962013-03-01 14:27:28 -080054const int Metrics::kMetricNetworkEapOuterProtocolMax =
55 Metrics::kEapOuterProtocolMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070056const char Metrics::kMetricNetworkPhyModeSuffix[] = "PhyMode";
Thieu Lead1ec2c2012-01-05 23:39:48 +000057const int Metrics::kMetricNetworkPhyModeMax = Metrics::kWiFiNetworkPhyModeMax;
mukesh agrawal132e96f2014-04-24 11:49:42 -070058const char Metrics::kMetricNetworkSecuritySuffix[] = "Security";
Thieu Lead1ec2c2012-01-05 23:39:48 +000059const int Metrics::kMetricNetworkSecurityMax = Metrics::kWiFiSecurityMax;
Thieu Le48e6d6d2011-12-06 00:40:27 +000060const char Metrics::kMetricNetworkServiceErrors[] =
61 "Network.Shill.ServiceErrors";
mukesh agrawal132e96f2014-04-24 11:49:42 -070062const char Metrics::kMetricNetworkSignalStrengthSuffix[] = "SignalStrength";
Paul Stewart23b393a2012-09-25 21:21:06 -070063const int Metrics::kMetricNetworkSignalStrengthMax = 200;
64const int Metrics::kMetricNetworkSignalStrengthMin = 0;
65const int Metrics::kMetricNetworkSignalStrengthNumBuckets = 40;
Thieu Lea20cbc22012-01-09 22:01:43 +000066
mukesh agrawalfacf7ad2014-09-30 15:25:44 -070067constexpr char
68 Metrics::kMetricRememberedSystemWiFiNetworkCountBySecurityModeFormat[];
69constexpr char
70 Metrics::kMetricRememberedUserWiFiNetworkCountBySecurityModeFormat[];
71
Paul Stewart4ef524d2014-07-23 13:11:29 -070072const char Metrics::kMetricRememberedWiFiNetworkCount[] =
73 "Network.Shill.WiFi.RememberedNetworkCount";
74const int Metrics::kMetricRememberedWiFiNetworkCountMax = 1024;
75const int Metrics::kMetricRememberedWiFiNetworkCountMin = 0;
76const int Metrics::kMetricRememberedWiFiNetworkCountNumBuckets = 32;
77
mukesh agrawal132e96f2014-04-24 11:49:42 -070078const char Metrics::kMetricTimeOnlineSecondsSuffix[] = "TimeOnline";
Thieu Lea20cbc22012-01-09 22:01:43 +000079const int Metrics::kMetricTimeOnlineSecondsMax = 8 * 60 * 60; // 8 hours
80const int Metrics::kMetricTimeOnlineSecondsMin = 1;
81
mukesh agrawal132e96f2014-04-24 11:49:42 -070082const char Metrics::kMetricTimeToConnectMillisecondsSuffix[] = "TimeToConnect";
Thieu Lecdb5a212013-01-25 11:17:18 -080083const int Metrics::kMetricTimeToConnectMillisecondsMax =
84 60 * 1000; // 60 seconds
85const int Metrics::kMetricTimeToConnectMillisecondsMin = 1;
86const int Metrics::kMetricTimeToConnectMillisecondsNumBuckets = 60;
87
mukesh agrawal132e96f2014-04-24 11:49:42 -070088const char Metrics::kMetricTimeToScanAndConnectMillisecondsSuffix[] =
89 "TimeToScanAndConnect";
Wade Guthrie44f290d2013-05-28 10:16:25 -070090
Thieu Lea20cbc22012-01-09 22:01:43 +000091const char Metrics::kMetricTimeToDropSeconds[] = "Network.Shill.TimeToDrop";;
92const int Metrics::kMetricTimeToDropSecondsMax = 8 * 60 * 60; // 8 hours
93const int Metrics::kMetricTimeToDropSecondsMin = 1;
94
mukesh agrawal132e96f2014-04-24 11:49:42 -070095const char Metrics::kMetricTimeToDisableMillisecondsSuffix[] = "TimeToDisable";
Thieu Lea2519bf2013-01-23 16:51:54 -080096const int Metrics::kMetricTimeToDisableMillisecondsMax =
97 60 * 1000; // 60 seconds
98const int Metrics::kMetricTimeToDisableMillisecondsMin = 1;
99const int Metrics::kMetricTimeToDisableMillisecondsNumBuckets = 60;
100
mukesh agrawal132e96f2014-04-24 11:49:42 -0700101const char Metrics::kMetricTimeToEnableMillisecondsSuffix[] = "TimeToEnable";
Thieu Lece4483e2013-01-23 15:12:03 -0800102const int Metrics::kMetricTimeToEnableMillisecondsMax =
103 60 * 1000; // 60 seconds
104const int Metrics::kMetricTimeToEnableMillisecondsMin = 1;
105const int Metrics::kMetricTimeToEnableMillisecondsNumBuckets = 60;
106
mukesh agrawal132e96f2014-04-24 11:49:42 -0700107const char Metrics::kMetricTimeToInitializeMillisecondsSuffix[] =
108 "TimeToInitialize";
Thieu Le769d50d2013-01-23 17:11:59 -0800109const int Metrics::kMetricTimeToInitializeMillisecondsMax =
110 30 * 1000; // 30 seconds
Thieu Lece4483e2013-01-23 15:12:03 -0800111const int Metrics::kMetricTimeToInitializeMillisecondsMin = 1;
Thieu Le769d50d2013-01-23 17:11:59 -0800112const int Metrics::kMetricTimeToInitializeMillisecondsNumBuckets = 30;
Thieu Lec8078a62013-01-22 18:01:12 -0800113
mukesh agrawal132e96f2014-04-24 11:49:42 -0700114const char Metrics::kMetricTimeResumeToReadyMillisecondsSuffix[] =
115 "TimeResumeToReady";
116const char Metrics::kMetricTimeToConfigMillisecondsSuffix[] = "TimeToConfig";
117const char Metrics::kMetricTimeToJoinMillisecondsSuffix[] = "TimeToJoin";
118const char Metrics::kMetricTimeToOnlineMillisecondsSuffix[] = "TimeToOnline";
119const char Metrics::kMetricTimeToPortalMillisecondsSuffix[] = "TimeToPortal";
Thieu Le18c11072013-01-28 17:21:37 -0800120
mukesh agrawal132e96f2014-04-24 11:49:42 -0700121const char Metrics::kMetricTimeToScanMillisecondsSuffix[] = "TimeToScan";
Thieu Le18c11072013-01-28 17:21:37 -0800122const int Metrics::kMetricTimeToScanMillisecondsMax = 180 * 1000; // 3 minutes
123const int Metrics::kMetricTimeToScanMillisecondsMin = 1;
124const int Metrics::kMetricTimeToScanMillisecondsNumBuckets = 90;
125
Thieu Lea20cbc22012-01-09 22:01:43 +0000126const int Metrics::kTimerHistogramMillisecondsMax = 45 * 1000;
127const int Metrics::kTimerHistogramMillisecondsMin = 1;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000128const int Metrics::kTimerHistogramNumBuckets = 50;
129
mukesh agrawal132e96f2014-04-24 11:49:42 -0700130const char Metrics::kMetricPortalAttemptsSuffix[] = "PortalAttempts";
Thieu Le85e050b2012-03-13 15:04:38 -0700131const int Metrics::kMetricPortalAttemptsMax =
132 PortalDetector::kMaxRequestAttempts;
133const int Metrics::kMetricPortalAttemptsMin = 1;
134const int Metrics::kMetricPortalAttemptsNumBuckets =
135 Metrics::kMetricPortalAttemptsMax;
136
mukesh agrawal132e96f2014-04-24 11:49:42 -0700137const char Metrics::kMetricPortalAttemptsToOnlineSuffix[] =
138 "PortalAttemptsToOnline";
Thieu Le85e050b2012-03-13 15:04:38 -0700139const int Metrics::kMetricPortalAttemptsToOnlineMax = 100;
140const int Metrics::kMetricPortalAttemptsToOnlineMin = 1;
141const int Metrics::kMetricPortalAttemptsToOnlineNumBuckets = 10;
142
mukesh agrawal132e96f2014-04-24 11:49:42 -0700143const char Metrics::kMetricPortalResultSuffix[] = "PortalResult";
Thieu Le85e050b2012-03-13 15:04:38 -0700144
Wade Guthrie60a37062013-04-02 11:39:09 -0700145const char Metrics::kMetricFrequenciesConnectedEver[] =
146 "Network.Shill.WiFi.FrequenciesConnectedEver";
147const int Metrics::kMetricFrequenciesConnectedMax = 50;
148const int Metrics::kMetricFrequenciesConnectedMin = 1;
149const int Metrics::kMetricFrequenciesConnectedNumBuckets = 50;
150
Wade Guthrieb9e0ee72013-05-31 09:23:30 -0700151const char Metrics::kMetricScanResult[] =
152 "Network.Shill.WiFi.ScanResult";
Wade Guthrief22681f2013-05-31 11:46:31 -0700153const char Metrics::kMetricWiFiScanTimeInEbusyMilliseconds[] =
154 "Network.Shill.WiFi.ScanTimeInEbusy";
155
Samuel Tanea7dcda2015-01-05 14:32:50 -0800156const char Metrics::kMetricTerminationActionTimeTaken[] =
157 "Network.Shill.TerminationActionTimeTaken";
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700158const char Metrics::kMetricTerminationActionResult[] =
159 "Network.Shill.TerminationActionResult";
Samuel Tanea7dcda2015-01-05 14:32:50 -0800160const int Metrics::kMetricTerminationActionTimeTakenMillisecondsMax = 20000;
161const int Metrics::kMetricTerminationActionTimeTakenMillisecondsMin = 1;
Arman Uguray6d528f12012-09-13 13:44:55 -0700162
Samuel Tanea7dcda2015-01-05 14:32:50 -0800163const char Metrics::kMetricSuspendActionTimeTaken[] =
164 "Network.Shill.SuspendActionTimeTaken";
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700165const char Metrics::kMetricSuspendActionResult[] =
166 "Network.Shill.SuspendActionResult";
Samuel Tanea7dcda2015-01-05 14:32:50 -0800167const int Metrics::kMetricSuspendActionTimeTakenMillisecondsMax = 20000;
168const int Metrics::kMetricSuspendActionTimeTakenMillisecondsMin = 1;
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700169
Samuel Tanea7dcda2015-01-05 14:32:50 -0800170const char Metrics::kMetricDarkResumeActionTimeTaken[] =
171 "Network.Shill.DarkResumeActionTimeTaken";
Samuel Tan68b73d22014-10-28 17:00:56 -0700172const char Metrics::kMetricDarkResumeActionResult[] =
173 "Network.Shill.DarkResumeActionResult";
Samuel Tanea7dcda2015-01-05 14:32:50 -0800174const int Metrics::kMetricDarkResumeActionTimeTakenMillisecondsMax = 20000;
175const int Metrics::kMetricDarkResumeActionTimeTakenMillisecondsMin = 1;
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800176const char Metrics::kMetricDarkResumeUnmatchedScanResultReceived[] =
177 "Network.Shill.WiFi.DarkResumeUnmatchedScanResultsReceived";
Samuel Tan68b73d22014-10-28 17:00:56 -0700178
Samuel Tan66bddc62014-11-13 20:01:04 -0800179const char Metrics::kMetricWakeOnWiFiFeaturesEnabledState[] =
Samuel Tan3294d462014-11-18 17:24:09 -0800180 "Network.Shill.WiFi.WakeOnWiFiFeaturesEnabledState";
Samuel Tana4933432015-02-06 18:20:41 -0800181const char Metrics::kMetricVerifyWakeOnWiFiSettingsResult[] =
182 "Network.Shill.WiFi.VerifyWakeOnWiFiSettingsResult";
183const char Metrics::kMetricWiFiConnectionStatusAfterWake[] =
184 "Network.Shill.WiFi.WiFiConnectionStatusAfterWake";
185const char Metrics::kMetricWakeOnWiFiThrottled[] =
186 "Network.Shill.WiFi.WakeOnWiFiThrottled";
187const char Metrics::kMetricWakeReasonReceivedBeforeOnDarkResume[] =
188 "Network.Shill.WiFi.WakeReasonReceivedBeforeOnDarkResume";
189const char Metrics::kMetricDarkResumeWakeReason[] =
190 "Network.Shill.WiFi.DarkResumeWakeReason";
Samuel Tand1bec5d2015-03-06 12:49:02 -0800191const char Metrics::kMetricDarkResumeScanType[] =
192 "Network.Shill.WiFi.DarkResumeScanType";
Samuel Tan029feac2015-03-27 16:53:01 -0700193const char Metrics::kMetricDarkResumeScanRetryResult[] =
194 "Network.Shill.WiFi.DarkResumeScanRetryResult";
195const char Metrics::kMetricDarkResumeScanNumRetries[] =
196 "Network.Shill.WiFi.DarkResumeScanNumRetries";
197const int Metrics::kMetricDarkResumeScanNumRetriesMax = 20;
198const int Metrics::kMetricDarkResumeScanNumRetriesMin = 0;
Samuel Tan66bddc62014-11-13 20:01:04 -0800199
Thieu Le48e6d6d2011-12-06 00:40:27 +0000200// static
mukesh agrawal132e96f2014-04-24 11:49:42 -0700201const char Metrics::kMetricServiceFixupEntriesSuffix[] = "ServiceFixupEntries";
Paul Stewart85aea152013-01-22 09:31:56 -0800202
203// static
Ben Chan7fab8972014-08-10 17:14:46 -0700204const uint16_t Metrics::kWiFiBandwidth5MHz = 5;
205const uint16_t Metrics::kWiFiBandwidth20MHz = 20;
206const uint16_t Metrics::kWiFiFrequency2412 = 2412;
207const uint16_t Metrics::kWiFiFrequency2472 = 2472;
208const uint16_t Metrics::kWiFiFrequency2484 = 2484;
209const uint16_t Metrics::kWiFiFrequency5170 = 5170;
210const uint16_t Metrics::kWiFiFrequency5180 = 5180;
211const uint16_t Metrics::kWiFiFrequency5230 = 5230;
212const uint16_t Metrics::kWiFiFrequency5240 = 5240;
213const uint16_t Metrics::kWiFiFrequency5320 = 5320;
214const uint16_t Metrics::kWiFiFrequency5500 = 5500;
215const uint16_t Metrics::kWiFiFrequency5700 = 5700;
216const uint16_t Metrics::kWiFiFrequency5745 = 5745;
217const uint16_t Metrics::kWiFiFrequency5825 = 5825;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000218
Thieu Leb84ba342012-03-02 15:15:19 -0800219// static
220const char Metrics::kMetricPowerManagerKey[] = "metrics";
221
Paul Stewartff845fc2012-08-07 07:28:44 -0700222// static
mukesh agrawal132e96f2014-04-24 11:49:42 -0700223const char Metrics::kMetricLinkMonitorFailureSuffix[] = "LinkMonitorFailure";
224const char Metrics::kMetricLinkMonitorResponseTimeSampleSuffix[] =
225 "LinkMonitorResponseTimeSample";
Paul Stewartf1961f82012-09-11 20:45:39 -0700226const int Metrics::kMetricLinkMonitorResponseTimeSampleMin = 0;
227const int Metrics::kMetricLinkMonitorResponseTimeSampleMax =
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700228 LinkMonitor::kDefaultTestPeriodMilliseconds;
Paul Stewartff845fc2012-08-07 07:28:44 -0700229const int Metrics::kMetricLinkMonitorResponseTimeSampleNumBuckets = 50;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700230const char Metrics::kMetricLinkMonitorSecondsToFailureSuffix[] =
231 "LinkMonitorSecondsToFailure";
Paul Stewartf1961f82012-09-11 20:45:39 -0700232const int Metrics::kMetricLinkMonitorSecondsToFailureMin = 0;
233const int Metrics::kMetricLinkMonitorSecondsToFailureMax = 7200;
Paul Stewart0443aa52012-08-09 10:43:50 -0700234const int Metrics::kMetricLinkMonitorSecondsToFailureNumBuckets = 50;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700235const char Metrics::kMetricLinkMonitorBroadcastErrorsAtFailureSuffix[] =
236 "LinkMonitorBroadcastErrorsAtFailure";
237const char Metrics::kMetricLinkMonitorUnicastErrorsAtFailureSuffix[] =
238 "LinkMonitorUnicastErrorsAtFailure";
Paul Stewartf1961f82012-09-11 20:45:39 -0700239const int Metrics::kMetricLinkMonitorErrorCountMin = 0;
240const int Metrics::kMetricLinkMonitorErrorCountMax =
Paul Stewart0443aa52012-08-09 10:43:50 -0700241 LinkMonitor::kFailureThreshold;
242const int Metrics::kMetricLinkMonitorErrorCountNumBuckets =
243 LinkMonitor::kFailureThreshold + 1;
Paul Stewartff845fc2012-08-07 07:28:44 -0700244
Wade Guthried4977f22012-08-22 12:37:54 -0700245// static
246const char Metrics::kMetricLinkClientDisconnectReason[] =
247 "Network.Shill.WiFi.ClientDisconnectReason";
248const char Metrics::kMetricLinkApDisconnectReason[] =
249 "Network.Shill.WiFi.ApDisconnectReason";
250const char Metrics::kMetricLinkClientDisconnectType[] =
251 "Network.Shill.WiFi.ClientDisconnectType";
252const char Metrics::kMetricLinkApDisconnectType[] =
253 "Network.Shill.WiFi.ApDisconnectType";
254
Thieu Le26fc01b2013-01-28 12:08:48 -0800255// static
Prathmesh Prabhu08757aa2013-05-15 17:17:33 -0700256const char Metrics::kMetricCellular3GPPRegistrationDelayedDrop[] =
257 "Network.Shill.Cellular.3GPPRegistrationDelayedDrop";
Thieu Le91fccf62013-04-22 15:23:16 -0700258const char Metrics::kMetricCellularAutoConnectTries[] =
259 "Network.Shill.Cellular.AutoConnectTries";
260const int Metrics::kMetricCellularAutoConnectTriesMax = 20;
261const int Metrics::kMetricCellularAutoConnectTriesMin = 1;
262const int Metrics::kMetricCellularAutoConnectTriesNumBuckets = 20;
263const char Metrics::kMetricCellularAutoConnectTotalTime[] =
264 "Network.Shill.Cellular.AutoConnectTotalTime";
265const int Metrics::kMetricCellularAutoConnectTotalTimeMax =
266 60 * 1000; // 60 seconds
267const int Metrics::kMetricCellularAutoConnectTotalTimeMin = 0;
268const int Metrics::kMetricCellularAutoConnectTotalTimeNumBuckets = 60;
Thieu Le26fc01b2013-01-28 12:08:48 -0800269const char Metrics::kMetricCellularDrop[] =
270 "Network.Shill.Cellular.Drop";
Thieu Leb7aa5f72013-01-31 15:57:48 -0800271// The format of FailureReason is different to other metrics because this
272// name is prepended to the error message before the entire string is sent
273// via SendUserActionToUMA.
274const char Metrics::kMetricCellularFailureReason[] =
275 "Network.Shill.Cellular.FailureReason: ";
Thieu Le91fccf62013-04-22 15:23:16 -0700276const char Metrics::kMetricCellularOutOfCreditsReason[] =
277 "Network.Shill.Cellular.OutOfCreditsReason";
Thieu Le26fc01b2013-01-28 12:08:48 -0800278const char Metrics::kMetricCellularSignalStrengthBeforeDrop[] =
279 "Network.Shill.Cellular.SignalStrengthBeforeDrop";
280const int Metrics::kMetricCellularSignalStrengthBeforeDropMax = 100;
281const int Metrics::kMetricCellularSignalStrengthBeforeDropMin = 0;
282const int Metrics::kMetricCellularSignalStrengthBeforeDropNumBuckets = 10;
283
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800284// static
Thieu Le5133b712013-02-19 14:47:21 -0800285const char Metrics::kMetricCorruptedProfile[] =
286 "Network.Shill.CorruptedProfile";
287
288// static
Paul Stewart91a43cb2013-03-02 21:34:15 -0800289const char Metrics::kMetricVpnDriver[] =
290 "Network.Shill.Vpn.Driver";
291const int Metrics::kMetricVpnDriverMax = Metrics::kVpnDriverMax;
292const char Metrics::kMetricVpnRemoteAuthenticationType[] =
293 "Network.Shill.Vpn.RemoteAuthenticationType";
294const int Metrics::kMetricVpnRemoteAuthenticationTypeMax =
295 Metrics::kVpnRemoteAuthenticationTypeMax;
296const char Metrics::kMetricVpnUserAuthenticationType[] =
297 "Network.Shill.Vpn.UserAuthenticationType";
298const int Metrics::kMetricVpnUserAuthenticationTypeMax =
299 Metrics::kVpnUserAuthenticationTypeMax;
300
mukesh agrawal132e96f2014-04-24 11:49:42 -0700301const char Metrics::kMetricExpiredLeaseLengthSecondsSuffix[] =
302 "ExpiredLeaseLengthSeconds";
Paul Stewart1f916e42013-12-23 09:52:54 -0800303const int Metrics::kMetricExpiredLeaseLengthSecondsMax =
304 7 * 24 * 60 * 60; // 7 days
305const int Metrics::kMetricExpiredLeaseLengthSecondsMin = 1;
306const int Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets =
307 Metrics::kMetricExpiredLeaseLengthSecondsMax;
308
Peter Qiu574996a2014-04-04 10:55:47 -0700309// static
310const char Metrics::kMetricWifiAutoConnectableServices[] =
Peter Qiu0dd90df2014-04-29 14:09:13 -0700311 "Network.Shill.WiFi.AutoConnectableServices";
Peter Qiu574996a2014-04-04 10:55:47 -0700312const int Metrics::kMetricWifiAutoConnectableServicesMax = 50;
313const int Metrics::kMetricWifiAutoConnectableServicesMin = 1;
314const int Metrics::kMetricWifiAutoConnectableServicesNumBuckets = 10;
315
316// static
317const char Metrics::kMetricWifiAvailableBSSes[] =
Peter Qiu0dd90df2014-04-29 14:09:13 -0700318 "Network.Shill.WiFi.AvailableBSSesAtConnect";
Peter Qiu574996a2014-04-04 10:55:47 -0700319const int Metrics::kMetricWifiAvailableBSSesMax = 50;
320const int Metrics::kMetricWifiAvailableBSSesMin = 1;
321const int Metrics::kMetricWifiAvailableBSSesNumBuckets = 10;
322
mukesh agrawalf7348732014-08-06 18:08:56 -0700323// static
324const char Metrics::kMetricWifiStoppedTxQueueReason[] =
325 "Network.Shill.WiFi.StoppedTxQueueReason";
326// Values are defined in mac80211_monitor.h.
327
328// static
329const char Metrics::kMetricWifiStoppedTxQueueLength[] =
330 "Network.Shill.WiFi.StoppedTxQueueLength";
331const int Metrics::kMetricWifiStoppedTxQueueLengthMax = 10000;
332const int Metrics::kMetricWifiStoppedTxQueueLengthMin = 1;
333const int Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets = 50;
334
Peter Qiu39d4af02014-04-14 12:24:01 -0700335// Number of services associated with currently connected network.
336const char Metrics::kMetricServicesOnSameNetwork[] =
337 "Network.Shill.ServicesOnSameNetwork";
338const int Metrics::kMetricServicesOnSameNetworkMax = 20;
339const int Metrics::kMetricServicesOnSameNetworkMin = 1;
340const int Metrics::kMetricServicesOnSameNetworkNumBuckets = 10;
341
Peter Qiue783f1c2014-05-02 11:42:33 -0700342// static
343const char Metrics::kMetricUserInitiatedEvents[] =
Peter Qiudc4e0992014-05-01 10:02:52 -0700344 "Network.Shill.UserInitiatedEvents";
Peter Qiue783f1c2014-05-02 11:42:33 -0700345
Peter Qiub9256f32014-05-09 15:27:29 -0700346// static
Peter Qiu8e430582014-04-30 14:12:37 -0700347const char Metrics::kMetricWifiTxBitrate[] =
348 "Network.Shill.WiFi.TransmitBitrateMbps";
349const int Metrics::kMetricWifiTxBitrateMax = 7000;
350const int Metrics::kMetricWifiTxBitrateMin = 1;
351const int Metrics::kMetricWifiTxBitrateNumBuckets = 100;
352
Peter Qiub9256f32014-05-09 15:27:29 -0700353// static
Peter Qiudc4e0992014-05-01 10:02:52 -0700354const char Metrics::kMetricWifiUserInitiatedConnectionResult[] =
355 "Network.Shill.WiFi.UserInitiatedConnectionResult";
356
Peter Qiub9256f32014-05-09 15:27:29 -0700357// static
Peter Qiud87179e2014-07-10 18:29:22 -0700358const char Metrics::kMetricWifiUserInitiatedConnectionFailureReason[] =
359 "Network.Shill.WiFi.UserInitiatedConnectionFailureReason";
360
361// static
Peter Qiuf18e7712014-05-20 09:59:46 -0700362const char Metrics::kMetricFallbackDNSTestResultSuffix[] =
363 "FallbackDNSTestResult";
Peter Qiub9256f32014-05-09 15:27:29 -0700364
Peter Qiudc335f82014-05-15 10:33:17 -0700365// static
366const char Metrics::kMetricNetworkProblemDetectedSuffix[] =
367 "NetworkProblemDetected";
368
Peter Qiu700de642014-07-14 16:31:30 -0700369// static
370const char Metrics::kMetricDeviceConnectionStatus[] =
371 "Network.Shill.DeviceConnectionStatus";
372
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700373// static
374const char Metrics::kMetricDhcpClientStatus[] =
Paul Stewarta72a79c2014-07-21 13:52:03 -0700375 "Network.Shill.DHCPClientStatus";
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700376
Peter Qiu300769e2014-08-27 11:48:45 -0700377// static
378const char Metrics::kMetricNetworkConnectionIPTypeSuffix[] =
379 "NetworkConnectionIPType";
380
381// static
382const char Metrics::kMetricIPv6ConnectivityStatusSuffix[] =
383 "IPv6ConnectivityStatus";
384
Peter Qiu94d18af2014-09-11 15:54:15 -0700385// static
386const char Metrics::kMetricDevicePresenceStatusSuffix[] =
387 "DevicePresenceStatus";
388
Peter Qiu9f5159e2014-09-12 16:50:14 -0700389// static
390const char Metrics::kMetricDeviceRemovedEvent[] =
391 "Network.Shill.DeviceRemovedEvent";
392
Samuel Tana4933432015-02-06 18:20:41 -0800393 // static
394 const char Metrics::kMetricUnreliableLinkSignalStrengthSuffix[] =
395 "UnreliableLinkSignalStrength";
Peter Qiua0572032014-09-26 10:07:37 -0700396const int Metrics::kMetricSerivceSignalStrengthMin = 0;
397const int Metrics::kMetricServiceSignalStrengthMax = 100;
398const int Metrics::kMetricServiceSignalStrengthNumBuckets = 40;
399
Paul Stewart8ae18742015-06-16 13:13:10 -0700400Metrics::Metrics(EventDispatcher* dispatcher)
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800401 : dispatcher_(dispatcher),
402 library_(&metrics_library_),
Thieu Lea20cbc22012-01-09 22:01:43 +0000403 last_default_technology_(Technology::kUnknown),
404 was_online_(false),
405 time_online_timer_(new chromeos_metrics::Timer),
Thieu Leb84ba342012-03-02 15:15:19 -0800406 time_to_drop_timer_(new chromeos_metrics::Timer),
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200407 time_resume_to_ready_timer_(new chromeos_metrics::Timer),
Arman Ugurayab22c162012-10-08 19:08:38 -0700408 time_termination_actions_timer(new chromeos_metrics::Timer),
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700409 time_suspend_actions_timer(new chromeos_metrics::Timer),
Samuel Tan68b73d22014-10-28 17:00:56 -0700410 time_dark_resume_actions_timer(new chromeos_metrics::Timer),
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800411 collect_bootstats_(true),
Samuel Tanc36b4102015-01-26 19:34:35 -0800412 num_scan_results_expected_in_dark_resume_(0),
Samuel Tana4933432015-02-06 18:20:41 -0800413 wake_on_wifi_throttled_(false),
Samuel Tan029feac2015-03-27 16:53:01 -0700414 wake_reason_received_(false),
415 dark_resume_scan_retries_(0) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000416 metrics_library_.Init();
417 chromeos_metrics::TimerReporter::set_metrics_lib(library_);
418}
419
420Metrics::~Metrics() {}
421
422// static
Ben Chan7fab8972014-08-10 17:14:46 -0700423Metrics::WiFiChannel Metrics::WiFiFrequencyToChannel(uint16_t frequency) {
Thieu Le48e6d6d2011-12-06 00:40:27 +0000424 WiFiChannel channel = kWiFiChannelUndef;
425 if (kWiFiFrequency2412 <= frequency && frequency <= kWiFiFrequency2472) {
426 if (((frequency - kWiFiFrequency2412) % kWiFiBandwidth5MHz) == 0)
427 channel = static_cast<WiFiChannel>(
428 kWiFiChannel2412 +
429 (frequency - kWiFiFrequency2412) / kWiFiBandwidth5MHz);
430 } else if (frequency == kWiFiFrequency2484) {
431 channel = kWiFiChannel2484;
432 } else if (kWiFiFrequency5170 <= frequency &&
433 frequency <= kWiFiFrequency5230) {
434 if ((frequency % kWiFiBandwidth20MHz) == 0)
435 channel = static_cast<WiFiChannel>(
436 kWiFiChannel5180 +
437 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
438 if ((frequency % kWiFiBandwidth20MHz) == 10)
439 channel = static_cast<WiFiChannel>(
440 kWiFiChannel5170 +
441 (frequency - kWiFiFrequency5170) / kWiFiBandwidth20MHz);
442 } else if (kWiFiFrequency5240 <= frequency &&
443 frequency <= kWiFiFrequency5320) {
444 if (((frequency - kWiFiFrequency5180) % kWiFiBandwidth20MHz) == 0)
445 channel = static_cast<WiFiChannel>(
446 kWiFiChannel5180 +
447 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz);
448 } else if (kWiFiFrequency5500 <= frequency &&
449 frequency <= kWiFiFrequency5700) {
450 if (((frequency - kWiFiFrequency5500) % kWiFiBandwidth20MHz) == 0)
451 channel = static_cast<WiFiChannel>(
452 kWiFiChannel5500 +
453 (frequency - kWiFiFrequency5500) / kWiFiBandwidth20MHz);
454 } else if (kWiFiFrequency5745 <= frequency &&
455 frequency <= kWiFiFrequency5825) {
456 if (((frequency - kWiFiFrequency5745) % kWiFiBandwidth20MHz) == 0)
457 channel = static_cast<WiFiChannel>(
458 kWiFiChannel5745 +
459 (frequency - kWiFiFrequency5745) / kWiFiBandwidth20MHz);
460 }
461 CHECK(kWiFiChannelUndef <= channel && channel < kWiFiChannelMax);
462
463 if (channel == kWiFiChannelUndef)
464 LOG(WARNING) << "no mapping for frequency " << frequency;
465 else
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700466 SLOG(nullptr, 3) << "mapped frequency " << frequency
467 << " to enum bucket " << channel;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000468
469 return channel;
470}
471
Thieu Lead1ec2c2012-01-05 23:39:48 +0000472// static
473Metrics::WiFiSecurity Metrics::WiFiSecurityStringToEnum(
Paul Stewart8ae18742015-06-16 13:13:10 -0700474 const string& security) {
Ben Chan923a5022013-09-20 11:23:23 -0700475 if (security == kSecurityNone) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000476 return kWiFiSecurityNone;
Ben Chan923a5022013-09-20 11:23:23 -0700477 } else if (security == kSecurityWep) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000478 return kWiFiSecurityWep;
Ben Chan923a5022013-09-20 11:23:23 -0700479 } else if (security == kSecurityWpa) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000480 return kWiFiSecurityWpa;
Ben Chan923a5022013-09-20 11:23:23 -0700481 } else if (security == kSecurityRsn) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000482 return kWiFiSecurityRsn;
Ben Chan923a5022013-09-20 11:23:23 -0700483 } else if (security == kSecurity8021x) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000484 return kWiFiSecurity8021x;
Ben Chan923a5022013-09-20 11:23:23 -0700485 } else if (security == kSecurityPsk) {
Thieu Lead1ec2c2012-01-05 23:39:48 +0000486 return kWiFiSecurityPsk;
487 } else {
488 return kWiFiSecurityUnknown;
489 }
490}
491
Thieu Le85e050b2012-03-13 15:04:38 -0700492// static
Paul Stewart8ae18742015-06-16 13:13:10 -0700493Metrics::WiFiApMode Metrics::WiFiApModeStringToEnum(const string& ap_mode) {
Ben Chan923a5022013-09-20 11:23:23 -0700494 if (ap_mode == kModeManaged) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700495 return kWiFiApModeManaged;
Ben Chan923a5022013-09-20 11:23:23 -0700496 } else if (ap_mode == kModeAdhoc) {
Paul Stewarte4cedde2013-07-17 08:56:44 -0700497 return kWiFiApModeAdHoc;
498 } else {
499 return kWiFiApModeUnknown;
500 }
501}
502
503// static
Paul Stewart21f40962013-03-01 14:27:28 -0800504Metrics::EapOuterProtocol Metrics::EapOuterProtocolStringToEnum(
Paul Stewart8ae18742015-06-16 13:13:10 -0700505 const string& outer) {
Ben Chan923a5022013-09-20 11:23:23 -0700506 if (outer == kEapMethodPEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800507 return kEapOuterProtocolPeap;
Ben Chan923a5022013-09-20 11:23:23 -0700508 } else if (outer == kEapMethodTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800509 return kEapOuterProtocolTls;
Ben Chan923a5022013-09-20 11:23:23 -0700510 } else if (outer == kEapMethodTTLS) {
Paul Stewart21f40962013-03-01 14:27:28 -0800511 return kEapOuterProtocolTtls;
Ben Chan923a5022013-09-20 11:23:23 -0700512 } else if (outer == kEapMethodLEAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800513 return kEapOuterProtocolLeap;
514 } else {
515 return kEapOuterProtocolUnknown;
516 }
517}
518
519// static
520Metrics::EapInnerProtocol Metrics::EapInnerProtocolStringToEnum(
Paul Stewart8ae18742015-06-16 13:13:10 -0700521 const string& inner) {
Paul Stewart21f40962013-03-01 14:27:28 -0800522 if (inner.empty()) {
523 return kEapInnerProtocolNone;
Ben Chan923a5022013-09-20 11:23:23 -0700524 } else if (inner == kEapPhase2AuthPEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800525 return kEapInnerProtocolPeapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700526 } else if (inner == kEapPhase2AuthPEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800527 return kEapInnerProtocolPeapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700528 } else if (inner == kEapPhase2AuthTTLSEAPMD5) {
Paul Stewart21f40962013-03-01 14:27:28 -0800529 return kEapInnerProtocolTtlsEapMd5;
Ben Chan923a5022013-09-20 11:23:23 -0700530 } else if (inner == kEapPhase2AuthTTLSEAPMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800531 return kEapInnerProtocolTtlsEapMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700532 } else if (inner == kEapPhase2AuthTTLSMSCHAPV2) {
Paul Stewart21f40962013-03-01 14:27:28 -0800533 return kEapInnerProtocolTtlsMschapv2;
Ben Chan923a5022013-09-20 11:23:23 -0700534 } else if (inner == kEapPhase2AuthTTLSMSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800535 return kEapInnerProtocolTtlsMschap;
Ben Chan923a5022013-09-20 11:23:23 -0700536 } else if (inner == kEapPhase2AuthTTLSPAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800537 return kEapInnerProtocolTtlsPap;
Ben Chan923a5022013-09-20 11:23:23 -0700538 } else if (inner == kEapPhase2AuthTTLSCHAP) {
Paul Stewart21f40962013-03-01 14:27:28 -0800539 return kEapInnerProtocolTtlsChap;
540 } else {
541 return kEapInnerProtocolUnknown;
542 }
543}
544
545// static
Thieu Le85e050b2012-03-13 15:04:38 -0700546Metrics::PortalResult Metrics::PortalDetectionResultToEnum(
Paul Stewart8ae18742015-06-16 13:13:10 -0700547 const PortalDetector::Result& portal_result) {
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700548 DCHECK(portal_result.final);
Thieu Le85e050b2012-03-13 15:04:38 -0700549 PortalResult retval = kPortalResultUnknown;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700550 ConnectivityTrial::Result result = portal_result.trial_result;
Thieu Le85e050b2012-03-13 15:04:38 -0700551 // The only time we should end a successful portal detection is when we're
552 // in the Content phase. If we end with kStatusSuccess in any other phase,
553 // then this indicates that something bad has happened.
554 switch (result.phase) {
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700555 case ConnectivityTrial::kPhaseDNS:
556 if (result.status == ConnectivityTrial::kStatusFailure)
Thieu Le85e050b2012-03-13 15:04:38 -0700557 retval = kPortalResultDNSFailure;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700558 else if (result.status == ConnectivityTrial::kStatusTimeout)
Thieu Le85e050b2012-03-13 15:04:38 -0700559 retval = kPortalResultDNSTimeout;
560 else
561 LOG(DFATAL) << __func__ << ": Final result status " << result.status
562 << " is not allowed in the DNS phase";
563 break;
564
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700565 case ConnectivityTrial::kPhaseConnection:
566 if (result.status == ConnectivityTrial::kStatusFailure)
Thieu Le85e050b2012-03-13 15:04:38 -0700567 retval = kPortalResultConnectionFailure;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700568 else if (result.status == ConnectivityTrial::kStatusTimeout)
Thieu Le85e050b2012-03-13 15:04:38 -0700569 retval = kPortalResultConnectionTimeout;
570 else
571 LOG(DFATAL) << __func__ << ": Final result status " << result.status
572 << " is not allowed in the Connection phase";
573 break;
574
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700575 case ConnectivityTrial::kPhaseHTTP:
576 if (result.status == ConnectivityTrial::kStatusFailure)
Thieu Le85e050b2012-03-13 15:04:38 -0700577 retval = kPortalResultHTTPFailure;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700578 else if (result.status == ConnectivityTrial::kStatusTimeout)
Thieu Le85e050b2012-03-13 15:04:38 -0700579 retval = kPortalResultHTTPTimeout;
580 else
581 LOG(DFATAL) << __func__ << ": Final result status " << result.status
582 << " is not allowed in the HTTP phase";
583 break;
584
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700585 case ConnectivityTrial::kPhaseContent:
586 if (result.status == ConnectivityTrial::kStatusSuccess)
Thieu Le85e050b2012-03-13 15:04:38 -0700587 retval = kPortalResultSuccess;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700588 else if (result.status == ConnectivityTrial::kStatusFailure)
Thieu Le85e050b2012-03-13 15:04:38 -0700589 retval = kPortalResultContentFailure;
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700590 else if (result.status == ConnectivityTrial::kStatusTimeout)
Thieu Le85e050b2012-03-13 15:04:38 -0700591 retval = kPortalResultContentTimeout;
592 else
593 LOG(DFATAL) << __func__ << ": Final result status " << result.status
594 << " is not allowed in the Content phase";
595 break;
596
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -0700597 case ConnectivityTrial::kPhaseUnknown:
Thieu Le85e050b2012-03-13 15:04:38 -0700598 retval = kPortalResultUnknown;
599 break;
600
601 default:
602 LOG(DFATAL) << __func__ << ": Invalid phase " << result.phase;
603 break;
604 }
605
606 return retval;
607}
608
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800609void Metrics::Start() {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700610 SLOG(this, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800611}
612
613void Metrics::Stop() {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700614 SLOG(this, 2) << __func__;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800615}
616
Paul Stewart8ae18742015-06-16 13:13:10 -0700617void Metrics::RegisterService(const Service& service) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700618 SLOG(this, 2) << __func__;
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700619 LOG_IF(WARNING, ContainsKey(services_metrics_, &service))
620 << "Repeatedly registering " << service.unique_name();
mukesh agrawal6cfe53f2013-08-13 13:39:01 -0700621 shared_ptr<ServiceMetrics> service_metrics(new ServiceMetrics());
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700622 services_metrics_[&service] = service_metrics;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000623 InitializeCommonServiceMetrics(service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000624}
625
Paul Stewart8ae18742015-06-16 13:13:10 -0700626void Metrics::DeregisterService(const Service& service) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700627 services_metrics_.erase(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000628}
629
630void Metrics::AddServiceStateTransitionTimer(
Paul Stewart8ae18742015-06-16 13:13:10 -0700631 const Service& service,
632 const string& histogram_name,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000633 Service::ConnectState start_state,
634 Service::ConnectState stop_state) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700635 SLOG(this, 2) << __func__ << ": adding " << histogram_name << " for "
636 << Service::ConnectStateToString(start_state) << " -> "
637 << Service::ConnectStateToString(stop_state);
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700638 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000639 if (it == services_metrics_.end()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700640 SLOG(this, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000641 DCHECK(false);
642 return;
643 }
Paul Stewart8ae18742015-06-16 13:13:10 -0700644 ServiceMetrics* service_metrics = it->second.get();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000645 CHECK(start_state < stop_state);
Paul Stewart8ae18742015-06-16 13:13:10 -0700646 chromeos_metrics::TimerReporter* timer =
Thieu Le48e6d6d2011-12-06 00:40:27 +0000647 new chromeos_metrics::TimerReporter(histogram_name,
Thieu Lea20cbc22012-01-09 22:01:43 +0000648 kTimerHistogramMillisecondsMin,
649 kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000650 kTimerHistogramNumBuckets);
651 service_metrics->timers.push_back(timer); // passes ownership.
652 service_metrics->start_on_state[start_state].push_back(timer);
653 service_metrics->stop_on_state[stop_state].push_back(timer);
654}
655
Paul Stewart8ae18742015-06-16 13:13:10 -0700656void Metrics::NotifyDefaultServiceChanged(const Service* service) {
Thieu Lea20cbc22012-01-09 22:01:43 +0000657 base::TimeDelta elapsed_seconds;
658
659 Technology::Identifier technology = (service) ? service->technology() :
660 Technology::kUnknown;
661 if (technology != last_default_technology_) {
662 if (last_default_technology_ != Technology::kUnknown) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700663 string histogram = GetFullMetricName(kMetricTimeOnlineSecondsSuffix,
Thieu Lea20cbc22012-01-09 22:01:43 +0000664 last_default_technology_);
665 time_online_timer_->GetElapsedTime(&elapsed_seconds);
666 SendToUMA(histogram,
667 elapsed_seconds.InSeconds(),
668 kMetricTimeOnlineSecondsMin,
669 kMetricTimeOnlineSecondsMax,
670 kTimerHistogramNumBuckets);
671 }
672 last_default_technology_ = technology;
673 time_online_timer_->Start();
674 }
675
Thieu Lea20cbc22012-01-09 22:01:43 +0000676 // Ignore changes that are not online/offline transitions; e.g.
677 // switching between wired and wireless. TimeToDrop measures
678 // time online regardless of how we are connected.
Ben Chancc225ef2014-09-30 13:26:51 -0700679 if ((service == nullptr && !was_online_) ||
680 (service != nullptr && was_online_))
Thieu Lea20cbc22012-01-09 22:01:43 +0000681 return;
682
Ben Chancc225ef2014-09-30 13:26:51 -0700683 if (service == nullptr) {
Thieu Lea20cbc22012-01-09 22:01:43 +0000684 time_to_drop_timer_->GetElapsedTime(&elapsed_seconds);
685 SendToUMA(kMetricTimeToDropSeconds,
686 elapsed_seconds.InSeconds(),
687 kMetricTimeToDropSecondsMin,
688 kMetricTimeToDropSecondsMax,
689 kTimerHistogramNumBuckets);
690 } else {
691 time_to_drop_timer_->Start();
692 }
693
Ben Chancc225ef2014-09-30 13:26:51 -0700694 was_online_ = (service != nullptr);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000695}
696
Paul Stewart8ae18742015-06-16 13:13:10 -0700697void Metrics::NotifyServiceStateChanged(const Service& service,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000698 Service::ConnectState new_state) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700699 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000700 if (it == services_metrics_.end()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700701 SLOG(this, 1) << "service not found";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000702 DCHECK(false);
703 return;
704 }
Paul Stewart8ae18742015-06-16 13:13:10 -0700705 ServiceMetrics* service_metrics = it->second.get();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000706 UpdateServiceStateTransitionMetrics(service_metrics, new_state);
707
708 if (new_state == Service::kStateFailure)
709 SendServiceFailure(service);
710
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200711 if (collect_bootstats_) {
Ben Chana0ddf462014-02-06 11:32:42 -0800712 bootstat_log(base::StringPrintf("network-%s-%s",
713 Technology::NameFromIdentifier(
714 service.technology()).c_str(),
715 service.GetStateString().c_str()).c_str());
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200716 }
717
Paul Stewart20088d82012-02-16 06:58:55 -0800718 if (new_state != Service::kStateConnected)
Thieu Le48e6d6d2011-12-06 00:40:27 +0000719 return;
720
Thieu Leb84ba342012-03-02 15:15:19 -0800721 base::TimeDelta time_resume_to_ready;
722 time_resume_to_ready_timer_->GetElapsedTime(&time_resume_to_ready);
723 time_resume_to_ready_timer_->Reset();
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700724 service.SendPostReadyStateMetrics(time_resume_to_ready.InMilliseconds());
Thieu Le48e6d6d2011-12-06 00:40:27 +0000725}
726
Paul Stewart8ae18742015-06-16 13:13:10 -0700727string Metrics::GetFullMetricName(const char* metric_suffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000728 Technology::Identifier technology_id) {
729 string technology = Technology::NameFromIdentifier(technology_id);
730 technology[0] = base::ToUpperASCII(technology[0]);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700731 return base::StringPrintf("%s.%s.%s", kMetricPrefix, technology.c_str(),
732 metric_suffix);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000733}
734
Paul Stewart8ae18742015-06-16 13:13:10 -0700735void Metrics::NotifyServiceDisconnect(const Service& service) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700736 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700737 string histogram = GetFullMetricName(kMetricDisconnectSuffix, technology);
Thieu Le67370f62012-02-14 23:01:42 +0000738 SendToUMA(histogram,
Wade Guthrie7ac610b2013-10-01 17:48:14 -0700739 service.explicitly_disconnected(),
Thieu Le67370f62012-02-14 23:01:42 +0000740 kMetricDisconnectMin,
741 kMetricDisconnectMax,
742 kMetricDisconnectNumBuckets);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000743}
744
Paul Stewart8ae18742015-06-16 13:13:10 -0700745void Metrics::NotifySignalAtDisconnect(const Service& service,
Wade Guthrie9ec08062013-09-25 15:22:24 -0700746 int16_t signal_strength) {
747 // Negate signal_strength (goes from dBm to -dBm) because the metrics don't
748 // seem to handle negative values well. Now everything's positive.
749 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -0700750 string histogram = GetFullMetricName(kMetricSignalAtDisconnectSuffix,
751 technology);
Wade Guthrie9ec08062013-09-25 15:22:24 -0700752 SendToUMA(histogram,
753 -signal_strength,
754 kMetricSignalAtDisconnectMin,
755 kMetricSignalAtDisconnectMax,
756 kMetricSignalAtDisconnectNumBuckets);
757}
758
Daniel Eratfac09532014-04-17 20:25:59 -0700759void Metrics::NotifySuspendDone() {
760 time_resume_to_ready_timer_->Start();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000761}
762
Samuel Tan66bddc62014-11-13 20:01:04 -0800763void Metrics::NotifyWakeOnWiFiFeaturesEnabledState(
764 WakeOnWiFiFeaturesEnabledState state) {
765 SendEnumToUMA(kMetricWakeOnWiFiFeaturesEnabledState, state,
766 kWakeOnWiFiFeaturesEnabledStateMax);
767}
768
Samuel Tanf144d5d2014-11-25 18:18:01 -0800769void Metrics::NotifyVerifyWakeOnWiFiSettingsResult(
770 VerifyWakeOnWiFiSettingsResult result) {
771 SendEnumToUMA(kMetricVerifyWakeOnWiFiSettingsResult, result,
772 kVerifyWakeOnWiFiSettingsResultMax);
773}
774
Samuel Tan1964b5d2014-12-02 10:11:21 -0800775void Metrics::NotifyConnectedToServiceAfterWake(
776 WiFiConnectionStatusAfterWake status) {
777 SendEnumToUMA(kMetricWiFiConnectionStatusAfterWake, status,
778 kWiFiConnetionStatusAfterWakeMax);
779}
780
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700781void Metrics::NotifyTerminationActionsStarted() {
Arman Ugurayab22c162012-10-08 19:08:38 -0700782 if (time_termination_actions_timer->HasStarted())
783 return;
784 time_termination_actions_timer->Start();
785}
786
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700787void Metrics::NotifyTerminationActionsCompleted(bool success) {
Arman Ugurayab22c162012-10-08 19:08:38 -0700788 if (!time_termination_actions_timer->HasStarted())
789 return;
790
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800791 TerminationActionResult result = success ? kTerminationActionResultSuccess
792 : kTerminationActionResultFailure;
Arman Ugurayab22c162012-10-08 19:08:38 -0700793
794 base::TimeDelta elapsed_time;
795 time_termination_actions_timer->GetElapsedTime(&elapsed_time);
796 time_termination_actions_timer->Reset();
797 string time_metric, result_metric;
Samuel Tanea7dcda2015-01-05 14:32:50 -0800798 time_metric = kMetricTerminationActionTimeTaken;
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700799 result_metric = kMetricTerminationActionResult;
Arman Ugurayab22c162012-10-08 19:08:38 -0700800
801 SendToUMA(time_metric,
802 elapsed_time.InMilliseconds(),
Samuel Tanea7dcda2015-01-05 14:32:50 -0800803 kMetricTerminationActionTimeTakenMillisecondsMin,
804 kMetricTerminationActionTimeTakenMillisecondsMax,
Arman Ugurayab22c162012-10-08 19:08:38 -0700805 kTimerHistogramNumBuckets);
806
807 SendEnumToUMA(result_metric,
808 result,
809 kTerminationActionResultMax);
810}
811
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700812void Metrics::NotifySuspendActionsStarted() {
813 if (time_suspend_actions_timer->HasStarted())
814 return;
815 time_suspend_actions_timer->Start();
Samuel Tanc36b4102015-01-26 19:34:35 -0800816 wake_on_wifi_throttled_ = false;
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700817}
818
819void Metrics::NotifySuspendActionsCompleted(bool success) {
820 if (!time_suspend_actions_timer->HasStarted())
821 return;
822
Samuel Tana4933432015-02-06 18:20:41 -0800823 // Reset for next dark resume.
824 wake_reason_received_ = false;
825
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800826 SuspendActionResult result =
827 success ? kSuspendActionResultSuccess : kSuspendActionResultFailure;
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700828
829 base::TimeDelta elapsed_time;
830 time_suspend_actions_timer->GetElapsedTime(&elapsed_time);
831 time_suspend_actions_timer->Reset();
832 string time_metric, result_metric;
Samuel Tanea7dcda2015-01-05 14:32:50 -0800833 time_metric = kMetricSuspendActionTimeTaken;
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700834 result_metric = kMetricSuspendActionResult;
835
836 SendToUMA(time_metric,
837 elapsed_time.InMilliseconds(),
Samuel Tanea7dcda2015-01-05 14:32:50 -0800838 kMetricSuspendActionTimeTakenMillisecondsMin,
839 kMetricSuspendActionTimeTakenMillisecondsMax,
Samuel Tanfbe8d2b2014-09-15 20:23:59 -0700840 kTimerHistogramNumBuckets);
841
842 SendEnumToUMA(result_metric,
843 result,
844 kSuspendActionResultMax);
845}
846
Samuel Tan68b73d22014-10-28 17:00:56 -0700847void Metrics::NotifyDarkResumeActionsStarted() {
848 if (time_dark_resume_actions_timer->HasStarted())
849 return;
850 time_dark_resume_actions_timer->Start();
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800851 num_scan_results_expected_in_dark_resume_ = 0;
Samuel Tan029feac2015-03-27 16:53:01 -0700852 dark_resume_scan_retries_ = 0;
Samuel Tan68b73d22014-10-28 17:00:56 -0700853}
854
855void Metrics::NotifyDarkResumeActionsCompleted(bool success) {
856 if (!time_dark_resume_actions_timer->HasStarted())
857 return;
858
Samuel Tana4933432015-02-06 18:20:41 -0800859 // Reset for next dark resume.
860 wake_reason_received_ = false;
861
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800862 DarkResumeActionResult result =
863 success ? kDarkResumeActionResultSuccess : kDarkResumeActionResultFailure;
Samuel Tan68b73d22014-10-28 17:00:56 -0700864
865 base::TimeDelta elapsed_time;
866 time_dark_resume_actions_timer->GetElapsedTime(&elapsed_time);
867 time_dark_resume_actions_timer->Reset();
Samuel Tan68b73d22014-10-28 17:00:56 -0700868
Samuel Tan029feac2015-03-27 16:53:01 -0700869 SendToUMA(kMetricDarkResumeActionTimeTaken,
Samuel Tan68b73d22014-10-28 17:00:56 -0700870 elapsed_time.InMilliseconds(),
Samuel Tanea7dcda2015-01-05 14:32:50 -0800871 kMetricDarkResumeActionTimeTakenMillisecondsMin,
872 kMetricDarkResumeActionTimeTakenMillisecondsMax,
Samuel Tan68b73d22014-10-28 17:00:56 -0700873 kTimerHistogramNumBuckets);
874
Samuel Tan029feac2015-03-27 16:53:01 -0700875 SendEnumToUMA(kMetricDarkResumeActionResult,
Samuel Tan68b73d22014-10-28 17:00:56 -0700876 result,
877 kDarkResumeActionResultMax);
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800878
879 DarkResumeUnmatchedScanResultReceived unmatched_scan_results_received =
880 (num_scan_results_expected_in_dark_resume_ < 0)
881 ? kDarkResumeUnmatchedScanResultsReceivedTrue
882 : kDarkResumeUnmatchedScanResultsReceivedFalse;
883 SendEnumToUMA(kMetricDarkResumeUnmatchedScanResultReceived,
884 unmatched_scan_results_received,
885 kDarkResumeUnmatchedScanResultsReceivedMax);
Samuel Tan029feac2015-03-27 16:53:01 -0700886
887 SendToUMA(kMetricDarkResumeScanNumRetries, dark_resume_scan_retries_,
888 kMetricDarkResumeScanNumRetriesMin,
889 kMetricDarkResumeScanNumRetriesMax, kTimerHistogramNumBuckets);
Samuel Tan0e0ac0d2014-12-29 16:03:42 -0800890}
891
892void Metrics::NotifyDarkResumeInitiateScan() {
893 ++num_scan_results_expected_in_dark_resume_;
894}
895
896void Metrics::NotifyDarkResumeScanResultsReceived() {
897 --num_scan_results_expected_in_dark_resume_;
Samuel Tan68b73d22014-10-28 17:00:56 -0700898}
899
Paul Stewartff845fc2012-08-07 07:28:44 -0700900void Metrics::NotifyLinkMonitorFailure(
Paul Stewart0443aa52012-08-09 10:43:50 -0700901 Technology::Identifier technology,
902 LinkMonitorFailure failure,
Paul Stewartf1961f82012-09-11 20:45:39 -0700903 int seconds_to_failure,
904 int broadcast_error_count,
905 int unicast_error_count) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700906 string histogram = GetFullMetricName(kMetricLinkMonitorFailureSuffix,
Paul Stewartff845fc2012-08-07 07:28:44 -0700907 technology);
908 SendEnumToUMA(histogram, failure, kLinkMonitorFailureMax);
Paul Stewart0443aa52012-08-09 10:43:50 -0700909
910 if (failure == kLinkMonitorFailureThresholdReached) {
911 if (seconds_to_failure > kMetricLinkMonitorSecondsToFailureMax) {
912 seconds_to_failure = kMetricLinkMonitorSecondsToFailureMax;
913 }
mukesh agrawal132e96f2014-04-24 11:49:42 -0700914 histogram = GetFullMetricName(kMetricLinkMonitorSecondsToFailureSuffix,
Paul Stewart0443aa52012-08-09 10:43:50 -0700915 technology);
916 SendToUMA(histogram,
917 seconds_to_failure,
918 kMetricLinkMonitorSecondsToFailureMin,
919 kMetricLinkMonitorSecondsToFailureMax,
920 kMetricLinkMonitorSecondsToFailureNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700921 histogram = GetFullMetricName(
922 kMetricLinkMonitorBroadcastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700923 SendToUMA(histogram,
924 broadcast_error_count,
925 kMetricLinkMonitorErrorCountMin,
926 kMetricLinkMonitorErrorCountMax,
927 kMetricLinkMonitorErrorCountNumBuckets);
mukesh agrawal132e96f2014-04-24 11:49:42 -0700928 histogram = GetFullMetricName(
929 kMetricLinkMonitorUnicastErrorsAtFailureSuffix, technology);
Paul Stewart0443aa52012-08-09 10:43:50 -0700930 SendToUMA(histogram,
931 unicast_error_count,
932 kMetricLinkMonitorErrorCountMin,
933 kMetricLinkMonitorErrorCountMax,
934 kMetricLinkMonitorErrorCountNumBuckets);
935 }
Paul Stewartff845fc2012-08-07 07:28:44 -0700936}
937
938void Metrics::NotifyLinkMonitorResponseTimeSampleAdded(
939 Technology::Identifier technology,
Paul Stewartf1961f82012-09-11 20:45:39 -0700940 int response_time_milliseconds) {
mukesh agrawal132e96f2014-04-24 11:49:42 -0700941 string histogram = GetFullMetricName(
942 kMetricLinkMonitorResponseTimeSampleSuffix, technology);
Paul Stewartff845fc2012-08-07 07:28:44 -0700943 SendToUMA(histogram,
944 response_time_milliseconds,
945 kMetricLinkMonitorResponseTimeSampleMin,
946 kMetricLinkMonitorResponseTimeSampleMax,
947 kMetricLinkMonitorResponseTimeSampleNumBuckets);
948}
949
Peter Qiu1a72f542015-04-14 16:31:36 -0700950#if !defined(DISABLE_WIFI)
951// TODO(zqiu): Change argument type from IEEE_80211::WiFiReasonCode to
952// Metrics::WiFiStatusType, to remove dependency for IEEE_80211.
Wade Guthried4977f22012-08-22 12:37:54 -0700953void Metrics::Notify80211Disconnect(WiFiDisconnectByWhom by_whom,
954 IEEE_80211::WiFiReasonCode reason) {
955 string metric_disconnect_reason;
956 string metric_disconnect_type;
957 WiFiStatusType type;
958
959 if (by_whom == kDisconnectedByAp) {
960 metric_disconnect_reason = kMetricLinkApDisconnectReason;
961 metric_disconnect_type = kMetricLinkApDisconnectType;
962 type = kStatusCodeTypeByAp;
963 } else {
964 metric_disconnect_reason = kMetricLinkClientDisconnectReason;
965 metric_disconnect_type = kMetricLinkClientDisconnectType;
Wade Guthrie60a37062013-04-02 11:39:09 -0700966 switch (reason) {
Wade Guthried4977f22012-08-22 12:37:54 -0700967 case IEEE_80211::kReasonCodeSenderHasLeft:
968 case IEEE_80211::kReasonCodeDisassociatedHasLeft:
969 type = kStatusCodeTypeByUser;
970 break;
971
972 case IEEE_80211::kReasonCodeInactivity:
973 type = kStatusCodeTypeConsideredDead;
974 break;
975
976 default:
977 type = kStatusCodeTypeByClient;
978 break;
979 }
980 }
981 SendEnumToUMA(metric_disconnect_reason, reason,
982 IEEE_80211::kStatusCodeMax);
983 SendEnumToUMA(metric_disconnect_type, type, kStatusCodeTypeMax);
984}
Peter Qiu1a72f542015-04-14 16:31:36 -0700985#endif // DISABLE_WIFI
Wade Guthried4977f22012-08-22 12:37:54 -0700986
Thieu Lec8078a62013-01-22 18:01:12 -0800987void Metrics::RegisterDevice(int interface_index,
988 Technology::Identifier technology) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700989 SLOG(this, 2) << __func__ << ": " << interface_index;
Thieu Lec8078a62013-01-22 18:01:12 -0800990 shared_ptr<DeviceMetrics> device_metrics(new DeviceMetrics);
991 devices_metrics_[interface_index] = device_metrics;
Thieu Le9abd6742013-01-23 23:35:37 -0800992 device_metrics->technology = technology;
mukesh agrawal132e96f2014-04-24 11:49:42 -0700993 string histogram = GetFullMetricName(
994 kMetricTimeToInitializeMillisecondsSuffix, technology);
Thieu Lec8078a62013-01-22 18:01:12 -0800995 device_metrics->initialization_timer.reset(
996 new chromeos_metrics::TimerReporter(
997 histogram,
998 kMetricTimeToInitializeMillisecondsMin,
999 kMetricTimeToInitializeMillisecondsMax,
1000 kMetricTimeToInitializeMillisecondsNumBuckets));
1001 device_metrics->initialization_timer->Start();
mukesh agrawal132e96f2014-04-24 11:49:42 -07001002 histogram = GetFullMetricName(kMetricTimeToEnableMillisecondsSuffix,
Thieu Lece4483e2013-01-23 15:12:03 -08001003 technology);
1004 device_metrics->enable_timer.reset(
1005 new chromeos_metrics::TimerReporter(
1006 histogram,
1007 kMetricTimeToEnableMillisecondsMin,
1008 kMetricTimeToEnableMillisecondsMax,
1009 kMetricTimeToEnableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -07001010 histogram = GetFullMetricName(kMetricTimeToDisableMillisecondsSuffix,
Thieu Lea2519bf2013-01-23 16:51:54 -08001011 technology);
1012 device_metrics->disable_timer.reset(
1013 new chromeos_metrics::TimerReporter(
1014 histogram,
1015 kMetricTimeToDisableMillisecondsMin,
1016 kMetricTimeToDisableMillisecondsMax,
1017 kMetricTimeToDisableMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -07001018 histogram = GetFullMetricName(kMetricTimeToScanMillisecondsSuffix,
Thieu Le18c11072013-01-28 17:21:37 -08001019 technology);
1020 device_metrics->scan_timer.reset(
1021 new chromeos_metrics::TimerReporter(
1022 histogram,
1023 kMetricTimeToScanMillisecondsMin,
1024 kMetricTimeToScanMillisecondsMax,
1025 kMetricTimeToScanMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -07001026 histogram = GetFullMetricName(kMetricTimeToConnectMillisecondsSuffix,
Thieu Lecdb5a212013-01-25 11:17:18 -08001027 technology);
1028 device_metrics->connect_timer.reset(
1029 new chromeos_metrics::TimerReporter(
1030 histogram,
1031 kMetricTimeToConnectMillisecondsMin,
1032 kMetricTimeToConnectMillisecondsMax,
1033 kMetricTimeToConnectMillisecondsNumBuckets));
mukesh agrawal132e96f2014-04-24 11:49:42 -07001034 histogram = GetFullMetricName(kMetricTimeToScanAndConnectMillisecondsSuffix,
Wade Guthrie44f290d2013-05-28 10:16:25 -07001035 technology);
1036 device_metrics->scan_connect_timer.reset(
1037 new chromeos_metrics::TimerReporter(
1038 histogram,
1039 kMetricTimeToScanMillisecondsMin,
1040 kMetricTimeToScanMillisecondsMax +
1041 kMetricTimeToConnectMillisecondsMax,
1042 kMetricTimeToScanMillisecondsNumBuckets +
1043 kMetricTimeToConnectMillisecondsNumBuckets));
Thieu Le7cf36b02013-01-30 17:15:56 -08001044 device_metrics->auto_connect_timer.reset(
1045 new chromeos_metrics::TimerReporter(
1046 kMetricCellularAutoConnectTotalTime,
1047 kMetricCellularAutoConnectTotalTimeMin,
1048 kMetricCellularAutoConnectTotalTimeMax,
1049 kMetricCellularAutoConnectTotalTimeNumBuckets));
Thieu Lec8078a62013-01-22 18:01:12 -08001050}
1051
Thieu Le9abd6742013-01-23 23:35:37 -08001052bool Metrics::IsDeviceRegistered(int interface_index,
1053 Technology::Identifier technology) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001054 SLOG(this, 2) << __func__ << ": interface index: " << interface_index
1055 << ", technology: " << technology;
Paul Stewart8ae18742015-06-16 13:13:10 -07001056 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001057 if (device_metrics == nullptr)
Thieu Le9abd6742013-01-23 23:35:37 -08001058 return false;
1059 // Make sure the device technologies match.
1060 return (technology == device_metrics->technology);
1061}
1062
Thieu Lec8078a62013-01-22 18:01:12 -08001063void Metrics::DeregisterDevice(int interface_index) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001064 SLOG(this, 2) << __func__ << ": interface index: " << interface_index;
Peter Qiu9f5159e2014-09-12 16:50:14 -07001065
Paul Stewart8ae18742015-06-16 13:13:10 -07001066 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001067 if (device_metrics != nullptr) {
Peter Qiu9f5159e2014-09-12 16:50:14 -07001068 NotifyDeviceRemovedEvent(device_metrics->technology);
1069 }
1070
Thieu Lec8078a62013-01-22 18:01:12 -08001071 devices_metrics_.erase(interface_index);
1072}
1073
1074void Metrics::NotifyDeviceInitialized(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001075 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001076 if (device_metrics == nullptr)
Thieu Lec8078a62013-01-22 18:01:12 -08001077 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -07001078 if (!device_metrics->initialization_timer->Stop())
1079 return;
Thieu Lec8078a62013-01-22 18:01:12 -08001080 device_metrics->initialization_timer->ReportMilliseconds();
1081}
1082
Thieu Lece4483e2013-01-23 15:12:03 -08001083void Metrics::NotifyDeviceEnableStarted(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001084 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001085 if (device_metrics == nullptr)
Thieu Lece4483e2013-01-23 15:12:03 -08001086 return;
1087 device_metrics->enable_timer->Start();
1088}
1089
1090void Metrics::NotifyDeviceEnableFinished(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001091 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001092 if (device_metrics == nullptr)
Thieu Lece4483e2013-01-23 15:12:03 -08001093 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -07001094 if (!device_metrics->enable_timer->Stop())
1095 return;
Thieu Lece4483e2013-01-23 15:12:03 -08001096 device_metrics->enable_timer->ReportMilliseconds();
1097}
1098
Thieu Lea2519bf2013-01-23 16:51:54 -08001099void Metrics::NotifyDeviceDisableStarted(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001100 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001101 if (device_metrics == nullptr)
Thieu Lea2519bf2013-01-23 16:51:54 -08001102 return;
1103 device_metrics->disable_timer->Start();
1104}
1105
1106void Metrics::NotifyDeviceDisableFinished(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001107 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001108 if (device_metrics == nullptr)
Thieu Lea2519bf2013-01-23 16:51:54 -08001109 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -07001110 if (!device_metrics->disable_timer->Stop())
1111 return;
Thieu Lea2519bf2013-01-23 16:51:54 -08001112 device_metrics->disable_timer->ReportMilliseconds();
1113}
1114
Thieu Le18c11072013-01-28 17:21:37 -08001115void Metrics::NotifyDeviceScanStarted(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001116 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001117 if (device_metrics == nullptr)
Thieu Le18c11072013-01-28 17:21:37 -08001118 return;
Thieu Le18c11072013-01-28 17:21:37 -08001119 device_metrics->scan_timer->Start();
Wade Guthrie44f290d2013-05-28 10:16:25 -07001120 device_metrics->scan_connect_timer->Start();
Thieu Le18c11072013-01-28 17:21:37 -08001121}
1122
1123void Metrics::NotifyDeviceScanFinished(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001124 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001125 if (device_metrics == nullptr)
Thieu Le18c11072013-01-28 17:21:37 -08001126 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -07001127 if (!device_metrics->scan_timer->Stop())
1128 return;
Wade Guthrie68d41092013-04-02 12:56:02 -07001129 // Don't send TimeToScan metrics if the elapsed time exceeds the max metrics
1130 // value. Huge scan times usually mean something's gone awry; for cellular,
1131 // for instance, this usually means that the modem is in an area without
1132 // service and we're not interested in this scenario.
Thieu Le18c11072013-01-28 17:21:37 -08001133 base::TimeDelta elapsed_time;
1134 device_metrics->scan_timer->GetElapsedTime(&elapsed_time);
1135 if (elapsed_time.InMilliseconds() <= kMetricTimeToScanMillisecondsMax)
1136 device_metrics->scan_timer->ReportMilliseconds();
1137}
1138
Wade Guthrie44f290d2013-05-28 10:16:25 -07001139void Metrics::ResetScanTimer(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001140 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001141 if (device_metrics == nullptr)
Wade Guthrie44f290d2013-05-28 10:16:25 -07001142 return;
1143 device_metrics->scan_timer->Reset();
1144}
1145
Thieu Le7cf36b02013-01-30 17:15:56 -08001146void Metrics::NotifyDeviceConnectStarted(int interface_index,
1147 bool is_auto_connecting) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001148 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001149 if (device_metrics == nullptr)
Thieu Lecdb5a212013-01-25 11:17:18 -08001150 return;
1151 device_metrics->connect_timer->Start();
Thieu Le7cf36b02013-01-30 17:15:56 -08001152
1153 if (is_auto_connecting) {
1154 device_metrics->auto_connect_tries++;
1155 if (device_metrics->auto_connect_tries == 1)
1156 device_metrics->auto_connect_timer->Start();
1157 } else {
1158 AutoConnectMetricsReset(device_metrics);
1159 }
Thieu Lecdb5a212013-01-25 11:17:18 -08001160}
1161
1162void Metrics::NotifyDeviceConnectFinished(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001163 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001164 if (device_metrics == nullptr)
Thieu Lecdb5a212013-01-25 11:17:18 -08001165 return;
Wade Guthrie091c41c2013-03-22 15:48:53 -07001166 if (!device_metrics->connect_timer->Stop())
1167 return;
Thieu Lecdb5a212013-01-25 11:17:18 -08001168 device_metrics->connect_timer->ReportMilliseconds();
Thieu Le7cf36b02013-01-30 17:15:56 -08001169
1170 if (device_metrics->auto_connect_tries > 0) {
Wade Guthrie091c41c2013-03-22 15:48:53 -07001171 if (!device_metrics->auto_connect_timer->Stop())
1172 return;
Thieu Le7cf36b02013-01-30 17:15:56 -08001173 base::TimeDelta elapsed_time;
1174 device_metrics->auto_connect_timer->GetElapsedTime(&elapsed_time);
1175 if (elapsed_time.InMilliseconds() > kMetricCellularAutoConnectTotalTimeMax)
1176 return;
1177 device_metrics->auto_connect_timer->ReportMilliseconds();
1178 SendToUMA(kMetricCellularAutoConnectTries,
1179 device_metrics->auto_connect_tries,
1180 kMetricCellularAutoConnectTriesMin,
1181 kMetricCellularAutoConnectTriesMax,
1182 kMetricCellularAutoConnectTriesNumBuckets);
1183 AutoConnectMetricsReset(device_metrics);
1184 }
Wade Guthrie44f290d2013-05-28 10:16:25 -07001185
1186 if (!device_metrics->scan_connect_timer->Stop())
1187 return;
Wade Guthrie44f290d2013-05-28 10:16:25 -07001188 device_metrics->scan_connect_timer->ReportMilliseconds();
1189}
1190
1191void Metrics::ResetConnectTimer(int interface_index) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001192 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index);
Ben Chancc225ef2014-09-30 13:26:51 -07001193 if (device_metrics == nullptr)
Wade Guthrie44f290d2013-05-28 10:16:25 -07001194 return;
1195 device_metrics->connect_timer->Reset();
1196 device_metrics->scan_connect_timer->Reset();
Thieu Lecdb5a212013-01-25 11:17:18 -08001197}
1198
Prathmesh Prabhu08757aa2013-05-15 17:17:33 -07001199void Metrics::Notify3GPPRegistrationDelayedDropPosted() {
1200 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1201 kCellular3GPPRegistrationDelayedDropPosted,
1202 kCellular3GPPRegistrationDelayedDropMax);
1203}
1204
1205void Metrics::Notify3GPPRegistrationDelayedDropCanceled() {
1206 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop,
1207 kCellular3GPPRegistrationDelayedDropCanceled,
1208 kCellular3GPPRegistrationDelayedDropMax);
1209}
1210
Paul Stewart8ae18742015-06-16 13:13:10 -07001211void Metrics::NotifyCellularDeviceDrop(const string& network_technology,
Ben Chan7fab8972014-08-10 17:14:46 -07001212 uint16_t signal_strength) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001213 SLOG(this, 2) << __func__ << ": " << network_technology
1214 << ", " << signal_strength;
Thieu Le26fc01b2013-01-28 12:08:48 -08001215 CellularDropTechnology drop_technology = kCellularDropTechnologyUnknown;
Ben Chan923a5022013-09-20 11:23:23 -07001216 if (network_technology == kNetworkTechnology1Xrtt) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001217 drop_technology = kCellularDropTechnology1Xrtt;
Ben Chan923a5022013-09-20 11:23:23 -07001218 } else if (network_technology == kNetworkTechnologyEdge) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001219 drop_technology = kCellularDropTechnologyEdge;
Ben Chan923a5022013-09-20 11:23:23 -07001220 } else if (network_technology == kNetworkTechnologyEvdo) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001221 drop_technology = kCellularDropTechnologyEvdo;
Ben Chan923a5022013-09-20 11:23:23 -07001222 } else if (network_technology == kNetworkTechnologyGprs) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001223 drop_technology = kCellularDropTechnologyGprs;
Ben Chan923a5022013-09-20 11:23:23 -07001224 } else if (network_technology == kNetworkTechnologyGsm) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001225 drop_technology = kCellularDropTechnologyGsm;
Ben Chan923a5022013-09-20 11:23:23 -07001226 } else if (network_technology == kNetworkTechnologyHspa) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001227 drop_technology = kCellularDropTechnologyHspa;
Ben Chan923a5022013-09-20 11:23:23 -07001228 } else if (network_technology == kNetworkTechnologyHspaPlus) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001229 drop_technology = kCellularDropTechnologyHspaPlus;
Ben Chan923a5022013-09-20 11:23:23 -07001230 } else if (network_technology == kNetworkTechnologyLte) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001231 drop_technology = kCellularDropTechnologyLte;
Ben Chan923a5022013-09-20 11:23:23 -07001232 } else if (network_technology == kNetworkTechnologyUmts) {
Thieu Le26fc01b2013-01-28 12:08:48 -08001233 drop_technology = kCellularDropTechnologyUmts;
1234 }
1235 SendEnumToUMA(kMetricCellularDrop,
1236 drop_technology,
1237 kCellularDropTechnologyMax);
1238 SendToUMA(kMetricCellularSignalStrengthBeforeDrop,
1239 signal_strength,
1240 kMetricCellularSignalStrengthBeforeDropMin,
1241 kMetricCellularSignalStrengthBeforeDropMax,
1242 kMetricCellularSignalStrengthBeforeDropNumBuckets);
1243}
1244
Paul Stewart8ae18742015-06-16 13:13:10 -07001245void Metrics::NotifyCellularDeviceFailure(const Error& error) {
Thieu Leb7aa5f72013-01-31 15:57:48 -08001246 library_->SendUserActionToUMA(
1247 kMetricCellularFailureReason + error.message());
1248}
1249
Thieu Le91fccf62013-04-22 15:23:16 -07001250void Metrics::NotifyCellularOutOfCredits(
1251 Metrics::CellularOutOfCreditsReason reason) {
1252 SendEnumToUMA(kMetricCellularOutOfCreditsReason,
1253 reason,
1254 kCellularOutOfCreditsReasonMax);
1255}
1256
Thieu Le5133b712013-02-19 14:47:21 -08001257void Metrics::NotifyCorruptedProfile() {
1258 SendEnumToUMA(kMetricCorruptedProfile,
1259 kCorruptedProfile,
1260 kCorruptedProfileMax);
1261}
1262
Peter Qiu574996a2014-04-04 10:55:47 -07001263void Metrics::NotifyWifiAutoConnectableServices(int num_services) {
1264 SendToUMA(kMetricWifiAutoConnectableServices,
1265 num_services,
1266 kMetricWifiAutoConnectableServicesMin,
1267 kMetricWifiAutoConnectableServicesMax,
1268 kMetricWifiAutoConnectableServicesNumBuckets);
1269}
1270
1271void Metrics::NotifyWifiAvailableBSSes(int num_bss) {
1272 SendToUMA(kMetricWifiAvailableBSSes,
1273 num_bss,
1274 kMetricWifiAvailableBSSesMin,
1275 kMetricWifiAvailableBSSesMax,
1276 kMetricWifiAvailableBSSesNumBuckets);
1277}
1278
Peter Qiu39d4af02014-04-14 12:24:01 -07001279void Metrics::NotifyServicesOnSameNetwork(int num_services) {
1280 SendToUMA(kMetricServicesOnSameNetwork,
1281 num_services,
1282 kMetricServicesOnSameNetworkMin,
1283 kMetricServicesOnSameNetworkMax,
1284 kMetricServicesOnSameNetworkNumBuckets);
1285}
1286
Peter Qiue783f1c2014-05-02 11:42:33 -07001287void Metrics::NotifyUserInitiatedEvent(int event) {
1288 SendEnumToUMA(kMetricUserInitiatedEvents,
1289 event,
1290 kUserInitiatedEventMax);
1291}
1292
Peter Qiu8e430582014-04-30 14:12:37 -07001293void Metrics::NotifyWifiTxBitrate(int bitrate) {
1294 SendToUMA(kMetricWifiTxBitrate,
1295 bitrate,
1296 kMetricWifiTxBitrateMin,
1297 kMetricWifiTxBitrateMax,
1298 kMetricWifiTxBitrateNumBuckets);
1299}
1300
Paul Stewart8ae18742015-06-16 13:13:10 -07001301void Metrics::NotifyUserInitiatedConnectionResult(const string& name,
Peter Qiudc4e0992014-05-01 10:02:52 -07001302 int result) {
1303 SendEnumToUMA(name,
1304 result,
1305 kUserInitiatedConnectionResultMax);
1306}
1307
Peter Qiud87179e2014-07-10 18:29:22 -07001308void Metrics::NotifyUserInitiatedConnectionFailureReason(
Paul Stewart8ae18742015-06-16 13:13:10 -07001309 const string& name, const Service::ConnectFailure failure) {
Peter Qiud87179e2014-07-10 18:29:22 -07001310 UserInitiatedConnectionFailureReason reason;
1311 switch (failure) {
1312 case Service::kFailureBadPassphrase:
1313 reason = kUserInitiatedConnectionFailureReasonBadPassphrase;
1314 break;
1315 case Service::kFailureBadWEPKey:
1316 reason = kUserInitiatedConnectionFailureReasonBadWEPKey;
1317 break;
1318 case Service::kFailureConnect:
1319 reason = kUserInitiatedConnectionFailureReasonConnect;
1320 break;
1321 case Service::kFailureDHCP:
1322 reason = kUserInitiatedConnectionFailureReasonDHCP;
1323 break;
1324 case Service::kFailureDNSLookup:
1325 reason = kUserInitiatedConnectionFailureReasonDNSLookup;
1326 break;
1327 case Service::kFailureEAPAuthentication:
1328 reason = kUserInitiatedConnectionFailureReasonEAPAuthentication;
1329 break;
1330 case Service::kFailureEAPLocalTLS:
1331 reason = kUserInitiatedConnectionFailureReasonEAPLocalTLS;
1332 break;
1333 case Service::kFailureEAPRemoteTLS:
1334 reason = kUserInitiatedConnectionFailureReasonEAPRemoteTLS;
1335 break;
1336 case Service::kFailureOutOfRange:
1337 reason = kUserInitiatedConnectionFailureReasonOutOfRange;
1338 break;
1339 case Service::kFailurePinMissing:
1340 reason = kUserInitiatedConnectionFailureReasonPinMissing;
1341 break;
1342 default:
1343 reason = kUserInitiatedConnectionFailureReasonUnknown;
1344 break;
1345 }
1346 SendEnumToUMA(name,
1347 reason,
1348 kUserInitiatedConnectionFailureReasonMax);
1349}
1350
Peter Qiuf18e7712014-05-20 09:59:46 -07001351void Metrics::NotifyFallbackDNSTestResult(Technology::Identifier technology_id,
1352 int result) {
1353 string histogram = GetFullMetricName(kMetricFallbackDNSTestResultSuffix,
1354 technology_id);
1355 SendEnumToUMA(histogram,
Peter Qiub9256f32014-05-09 15:27:29 -07001356 result,
Peter Qiuf18e7712014-05-20 09:59:46 -07001357 kFallbackDNSTestResultMax);
Peter Qiub9256f32014-05-09 15:27:29 -07001358}
1359
Peter Qiudc335f82014-05-15 10:33:17 -07001360void Metrics::NotifyNetworkProblemDetected(Technology::Identifier technology_id,
1361 int reason) {
1362 string histogram = GetFullMetricName(kMetricNetworkProblemDetectedSuffix,
1363 technology_id);
1364 SendEnumToUMA(histogram,
1365 reason,
1366 kNetworkProblemMax);
1367}
1368
Peter Qiu700de642014-07-14 16:31:30 -07001369void Metrics::NotifyDeviceConnectionStatus(ConnectionStatus status) {
1370 SendEnumToUMA(kMetricDeviceConnectionStatus, status, kConnectionStatusMax);
1371}
1372
Paul Stewart3bdf1ab2014-07-17 19:22:26 -07001373void Metrics::NotifyDhcpClientStatus(DhcpClientStatus status) {
1374 SendEnumToUMA(kMetricDhcpClientStatus, status, kDhcpClientStatusMax);
1375}
1376
Peter Qiu300769e2014-08-27 11:48:45 -07001377void Metrics::NotifyNetworkConnectionIPType(
1378 Technology::Identifier technology_id, NetworkConnectionIPType type) {
1379 string histogram = GetFullMetricName(kMetricNetworkConnectionIPTypeSuffix,
1380 technology_id);
1381 SendEnumToUMA(histogram, type, kNetworkConnectionIPTypeMax);
1382}
1383
1384void Metrics::NotifyIPv6ConnectivityStatus(Technology::Identifier technology_id,
1385 bool status) {
1386 string histogram = GetFullMetricName(kMetricIPv6ConnectivityStatusSuffix,
1387 technology_id);
1388 IPv6ConnectivityStatus ipv6_status = status ? kIPv6ConnectivityStatusYes
1389 : kIPv6ConnectivityStatusNo;
1390 SendEnumToUMA(histogram, ipv6_status, kIPv6ConnectivityStatusMax);
1391}
1392
Peter Qiu94d18af2014-09-11 15:54:15 -07001393void Metrics::NotifyDevicePresenceStatus(Technology::Identifier technology_id,
1394 bool status) {
1395 string histogram = GetFullMetricName(kMetricDevicePresenceStatusSuffix,
1396 technology_id);
1397 DevicePresenceStatus presence = status ? kDevicePresenceStatusYes
1398 : kDevicePresenceStatusNo;
1399 SendEnumToUMA(histogram, presence, kDevicePresenceStatusMax);
1400}
1401
Peter Qiu9f5159e2014-09-12 16:50:14 -07001402void Metrics::NotifyDeviceRemovedEvent(Technology::Identifier technology_id) {
1403 DeviceTechnologyType type;
1404 switch (technology_id) {
1405 case Technology::kEthernet:
1406 type = kDeviceTechnologyTypeEthernet;
1407 break;
1408 case Technology::kWifi:
1409 type = kDeviceTechnologyTypeWifi;
1410 break;
1411 case Technology::kWiMax:
1412 type = kDeviceTechnologyTypeWimax;
1413 break;
1414 case Technology::kCellular:
1415 type = kDeviceTechnologyTypeCellular;
1416 break;
1417 default:
1418 type = kDeviceTechnologyTypeUnknown;
1419 break;
1420 }
1421 SendEnumToUMA(kMetricDeviceRemovedEvent, type, kDeviceTechnologyTypeMax);
1422}
1423
Peter Qiua0572032014-09-26 10:07:37 -07001424void Metrics::NotifyUnreliableLinkSignalStrength(
1425 Technology::Identifier technology_id, int signal_strength) {
1426 string histogram = GetFullMetricName(
1427 kMetricUnreliableLinkSignalStrengthSuffix, technology_id);
1428 SendToUMA(histogram,
1429 signal_strength,
1430 kMetricSerivceSignalStrengthMin,
1431 kMetricServiceSignalStrengthMax,
1432 kMetricServiceSignalStrengthNumBuckets);
1433}
1434
Paul Stewart8ae18742015-06-16 13:13:10 -07001435bool Metrics::SendEnumToUMA(const string& name, int sample, int max) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001436 SLOG(this, 5)
mukesh agrawal94cde582013-08-12 17:55:33 -07001437 << "Sending enum " << name << " with value " << sample << ".";
Thieu Le48e6d6d2011-12-06 00:40:27 +00001438 return library_->SendEnumToUMA(name, sample, max);
1439}
1440
Paul Stewart8ae18742015-06-16 13:13:10 -07001441bool Metrics::SendToUMA(const string& name, int sample, int min, int max,
Thieu Lea20cbc22012-01-09 22:01:43 +00001442 int num_buckets) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001443 SLOG(this, 5)
mukesh agrawal94cde582013-08-12 17:55:33 -07001444 << "Sending metric " << name << " with value " << sample << ".";
Thieu Lea20cbc22012-01-09 22:01:43 +00001445 return library_->SendToUMA(name, sample, min, max, num_buckets);
1446}
1447
Samuel Tanc36b4102015-01-26 19:34:35 -08001448void Metrics::NotifyWakeOnWiFiThrottled() {
1449 wake_on_wifi_throttled_ = true;
1450}
1451
1452void Metrics::NotifySuspendWithWakeOnWiFiEnabledDone() {
1453 WakeOnWiFiThrottled throttled_result = wake_on_wifi_throttled_
1454 ? kWakeOnWiFiThrottledTrue
1455 : kWakeOnWiFiThrottledFalse;
1456 SendEnumToUMA(kMetricWakeOnWiFiThrottled, throttled_result,
1457 kWakeOnWiFiThrottledMax);
1458}
1459
Samuel Tana4933432015-02-06 18:20:41 -08001460void Metrics::NotifyWakeupReasonReceived() { wake_reason_received_ = true; }
1461
Peter Qiu1a72f542015-04-14 16:31:36 -07001462#if !defined(DISABLE_WIFI)
1463// TODO(zqiu): Change argument type from WakeOnWiFi::WakeOnWiFiTrigger to
1464// Metrics::DarkResumeWakeReason, to remove the dependency for WakeOnWiFi.
1465// to remove the dependency for WakeOnWiFi.
Samuel Tana4933432015-02-06 18:20:41 -08001466void Metrics::NotifyWakeOnWiFiOnDarkResume(
1467 WakeOnWiFi::WakeOnWiFiTrigger reason) {
1468 WakeReasonReceivedBeforeOnDarkResume result =
1469 wake_reason_received_ ? kWakeReasonReceivedBeforeOnDarkResumeTrue
1470 : kWakeReasonReceivedBeforeOnDarkResumeFalse;
1471
1472 SendEnumToUMA(kMetricWakeReasonReceivedBeforeOnDarkResume, result,
1473 kWakeReasonReceivedBeforeOnDarkResumeMax);
1474
1475 DarkResumeWakeReason wake_reason;
1476 switch (reason) {
1477 case WakeOnWiFi::kWakeTriggerPattern:
1478 wake_reason = kDarkResumeWakeReasonPattern;
1479 break;
1480 case WakeOnWiFi::kWakeTriggerDisconnect:
1481 wake_reason = kDarkResumeWakeReasonDisconnect;
1482 break;
1483 case WakeOnWiFi::kWakeTriggerSSID:
1484 wake_reason = kDarkResumeWakeReasonSSID;
1485 break;
1486 case WakeOnWiFi::kWakeTriggerUnsupported:
1487 default:
1488 wake_reason = kDarkResumeWakeReasonUnsupported;
1489 break;
1490 }
1491 SendEnumToUMA(kMetricDarkResumeWakeReason, wake_reason,
1492 kDarkResumeWakeReasonMax);
1493}
Peter Qiu1a72f542015-04-14 16:31:36 -07001494#endif // DISABLE_WIFI
Samuel Tana4933432015-02-06 18:20:41 -08001495
Samuel Tand1bec5d2015-03-06 12:49:02 -08001496void Metrics::NotifyScanStartedInDarkResume(bool is_active_scan) {
1497 DarkResumeScanType scan_type =
1498 is_active_scan ? kDarkResumeScanTypeActive : kDarkResumeScanTypePassive;
1499 SendEnumToUMA(kMetricDarkResumeScanType, scan_type, kDarkResumeScanTypeMax);
1500}
1501
Samuel Tan029feac2015-03-27 16:53:01 -07001502void Metrics::NotifyDarkResumeScanRetry() {
1503 ++dark_resume_scan_retries_;
1504}
1505
1506void Metrics::NotifyBeforeSuspendActions(bool is_connected,
1507 bool in_dark_resume) {
1508 if (in_dark_resume && dark_resume_scan_retries_) {
1509 DarkResumeScanRetryResult connect_result =
1510 is_connected ? kDarkResumeScanRetryResultConnected
1511 : kDarkResumeScanRetryResultNotConnected;
1512 SendEnumToUMA(kMetricDarkResumeScanRetryResult, connect_result,
1513 kDarkResumeScanRetryResultMax);
1514 }
1515}
1516
Paul Stewart8ae18742015-06-16 13:13:10 -07001517void Metrics::InitializeCommonServiceMetrics(const Service& service) {
Wade Guthrie7ac610b2013-10-01 17:48:14 -07001518 Technology::Identifier technology = service.technology();
mukesh agrawal132e96f2014-04-24 11:49:42 -07001519 string histogram = GetFullMetricName(kMetricTimeToConfigMillisecondsSuffix,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001520 technology);
1521 AddServiceStateTransitionTimer(
1522 service,
1523 histogram,
1524 Service::kStateConfiguring,
Paul Stewart20088d82012-02-16 06:58:55 -08001525 Service::kStateConnected);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001526 histogram = GetFullMetricName(kMetricTimeToPortalMillisecondsSuffix,
1527 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001528 AddServiceStateTransitionTimer(
1529 service,
1530 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001531 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001532 Service::kStatePortal);
mukesh agrawal132e96f2014-04-24 11:49:42 -07001533 histogram = GetFullMetricName(kMetricTimeToOnlineMillisecondsSuffix,
1534 technology);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001535 AddServiceStateTransitionTimer(
1536 service,
1537 histogram,
Paul Stewart20088d82012-02-16 06:58:55 -08001538 Service::kStateConnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001539 Service::kStateOnline);
1540}
1541
1542void Metrics::UpdateServiceStateTransitionMetrics(
Paul Stewart8ae18742015-06-16 13:13:10 -07001543 ServiceMetrics* service_metrics,
Thieu Le48e6d6d2011-12-06 00:40:27 +00001544 Service::ConnectState new_state) {
Paul Stewart8ae18742015-06-16 13:13:10 -07001545 const char* state_string = Service::ConnectStateToString(new_state);
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001546 SLOG(this, 5) << __func__ << ": new_state=" << state_string;
Paul Stewart8ae18742015-06-16 13:13:10 -07001547 TimerReportersList& start_timers = service_metrics->start_on_state[new_state];
1548 for (auto& start_timer : start_timers) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001549 SLOG(this, 5) << "Starting timer for " << start_timer->histogram_name()
1550 << " due to new state " << state_string << ".";
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001551 start_timer->Start();
1552 }
Thieu Le48e6d6d2011-12-06 00:40:27 +00001553
Paul Stewart8ae18742015-06-16 13:13:10 -07001554 TimerReportersList& stop_timers = service_metrics->stop_on_state[new_state];
1555 for (auto& stop_timer : stop_timers) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001556 SLOG(this, 5) << "Stopping timer for " << stop_timer->histogram_name()
1557 << " due to new state " << state_string << ".";
mukesh agrawal6f4ab422013-08-13 12:51:55 -07001558 if (stop_timer->Stop())
1559 stop_timer->ReportMilliseconds();
Thieu Le48e6d6d2011-12-06 00:40:27 +00001560 }
1561}
1562
Paul Stewart8ae18742015-06-16 13:13:10 -07001563void Metrics::SendServiceFailure(const Service& service) {
Peter Qiu27df3642014-09-19 09:50:54 -07001564 NetworkServiceError error = kNetworkServiceErrorUnknown;
1565 // Explicitly map all possible failures. So when new failures are added,
1566 // they will need to be mapped as well. Otherwise, the compiler will
1567 // complain.
1568 switch (service.failure()) {
1569 case Service::kFailureUnknown:
1570 case Service::kFailureMax:
1571 error = kNetworkServiceErrorUnknown;
1572 break;
1573 case Service::kFailureAAA:
1574 error = kNetworkServiceErrorAAA;
1575 break;
1576 case Service::kFailureActivation:
1577 error = kNetworkServiceErrorActivation;
1578 break;
1579 case Service::kFailureBadPassphrase:
1580 error = kNetworkServiceErrorBadPassphrase;
1581 break;
1582 case Service::kFailureBadWEPKey:
1583 error = kNetworkServiceErrorBadWEPKey;
1584 break;
1585 case Service::kFailureConnect:
1586 error = kNetworkServiceErrorConnect;
1587 break;
1588 case Service::kFailureDHCP:
1589 error = kNetworkServiceErrorDHCP;
1590 break;
1591 case Service::kFailureDNSLookup:
1592 error = kNetworkServiceErrorDNSLookup;
1593 break;
1594 case Service::kFailureEAPAuthentication:
1595 error = kNetworkServiceErrorEAPAuthentication;
1596 break;
1597 case Service::kFailureEAPLocalTLS:
1598 error = kNetworkServiceErrorEAPLocalTLS;
1599 break;
1600 case Service::kFailureEAPRemoteTLS:
1601 error = kNetworkServiceErrorEAPRemoteTLS;
1602 break;
1603 case Service::kFailureHTTPGet:
1604 error = kNetworkServiceErrorHTTPGet;
1605 break;
1606 case Service::kFailureIPSecCertAuth:
1607 error = kNetworkServiceErrorIPSecCertAuth;
1608 break;
1609 case Service::kFailureIPSecPSKAuth:
1610 error = kNetworkServiceErrorIPSecPSKAuth;
1611 break;
1612 case Service::kFailureInternal:
1613 error = kNetworkServiceErrorInternal;
1614 break;
1615 case Service::kFailureNeedEVDO:
1616 error = kNetworkServiceErrorNeedEVDO;
1617 break;
1618 case Service::kFailureNeedHomeNetwork:
1619 error = kNetworkServiceErrorNeedHomeNetwork;
1620 break;
1621 case Service::kFailureOTASP:
1622 error = kNetworkServiceErrorOTASP;
1623 break;
1624 case Service::kFailureOutOfRange:
1625 error = kNetworkServiceErrorOutOfRange;
1626 break;
1627 case Service::kFailurePPPAuth:
1628 error = kNetworkServiceErrorPPPAuth;
1629 break;
1630 case Service::kFailurePinMissing:
1631 error = kNetworkServiceErrorPinMissing;
1632 break;
1633 }
1634
Thieu Le48e6d6d2011-12-06 00:40:27 +00001635 library_->SendEnumToUMA(kMetricNetworkServiceErrors,
Peter Qiu27df3642014-09-19 09:50:54 -07001636 error,
1637 kNetworkServiceErrorMax);
Thieu Le48e6d6d2011-12-06 00:40:27 +00001638}
1639
Paul Stewart8ae18742015-06-16 13:13:10 -07001640Metrics::DeviceMetrics* Metrics::GetDeviceMetrics(int interface_index) const {
Thieu Le9abd6742013-01-23 23:35:37 -08001641 DeviceMetricsLookupMap::const_iterator it =
1642 devices_metrics_.find(interface_index);
Thieu Lece4483e2013-01-23 15:12:03 -08001643 if (it == devices_metrics_.end()) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -07001644 SLOG(this, 2) << __func__ << ": device " << interface_index
1645 << " not found";
Ben Chancc225ef2014-09-30 13:26:51 -07001646 return nullptr;
Thieu Lece4483e2013-01-23 15:12:03 -08001647 }
1648 return it->second.get();
1649}
1650
Paul Stewart8ae18742015-06-16 13:13:10 -07001651void Metrics::AutoConnectMetricsReset(DeviceMetrics* device_metrics) {
Thieu Le7cf36b02013-01-30 17:15:56 -08001652 device_metrics->auto_connect_tries = 0;
1653 device_metrics->auto_connect_timer->Reset();
1654}
1655
Paul Stewart8ae18742015-06-16 13:13:10 -07001656void Metrics::set_library(MetricsLibraryInterface* library) {
Thieu Le48e6d6d2011-12-06 00:40:27 +00001657 chromeos_metrics::TimerReporter::set_metrics_lib(library);
1658 library_ = library;
1659}
1660
1661} // namespace shill