1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/metrics.h" 18 19 #include <base/strings/string_util.h> 20 #include <base/strings/stringprintf.h> 21 #if defined(__ANDROID__) 22 #include <dbus/service_constants.h> 23 #else 24 #include <chromeos/dbus/service_constants.h> 25 #endif // __ANDROID__ 26 #if !defined(__ANDROID__) 27 #include <metrics/bootstat.h> 28 #endif // __ANDROID__ 29 30 #include "shill/connection_diagnostics.h" 31 #include "shill/link_monitor.h" 32 #include "shill/logging.h" 33 34 using std::string; 35 using std::shared_ptr; 36 37 namespace shill { 38 39 namespace Logging { 40 static auto kModuleLogScope = ScopeLogger::kMetrics; 41 static string ObjectID(const Metrics* m) { return "(metrics)"; } 42 } 43 44 static const char kMetricPrefix[] = "Network.Shill"; 45 46 // static 47 // Our disconnect enumeration values are 0 (System Disconnect) and 48 // 1 (User Disconnect), see histograms.xml, but Chrome needs a minimum 49 // enum value of 1 and the minimum number of buckets needs to be 3 (see 50 // histogram.h). Instead of remapping System Disconnect to 1 and 51 // User Disconnect to 2, we can just leave the enumerated values as-is 52 // because Chrome implicitly creates a [0-1) bucket for us. Using Min=1, 53 // Max=2 and NumBuckets=3 gives us the following three buckets: 54 // [0-1), [1-2), [2-INT_MAX). We end up with an extra bucket [2-INT_MAX) 55 // that we can safely ignore. 56 const char Metrics::kMetricDisconnectSuffix[] = "Disconnect"; 57 const int Metrics::kMetricDisconnectMax = 2; 58 const int Metrics::kMetricDisconnectMin = 1; 59 const int Metrics::kMetricDisconnectNumBuckets = 3; 60 61 const char Metrics::kMetricSignalAtDisconnectSuffix[] = "SignalAtDisconnect"; 62 const int Metrics::kMetricSignalAtDisconnectMin = 0; 63 const int Metrics::kMetricSignalAtDisconnectMax = 200; 64 const int Metrics::kMetricSignalAtDisconnectNumBuckets = 40; 65 66 const char Metrics::kMetricNetworkApModeSuffix[] = "ApMode"; 67 const char Metrics::kMetricNetworkChannelSuffix[] = "Channel"; 68 const int Metrics::kMetricNetworkChannelMax = Metrics::kWiFiChannelMax; 69 const char Metrics::kMetricNetworkEapInnerProtocolSuffix[] = "EapInnerProtocol"; 70 const int Metrics::kMetricNetworkEapInnerProtocolMax = 71 Metrics::kEapInnerProtocolMax; 72 const char Metrics::kMetricNetworkEapOuterProtocolSuffix[] = "EapOuterProtocol"; 73 const int Metrics::kMetricNetworkEapOuterProtocolMax = 74 Metrics::kEapOuterProtocolMax; 75 const char Metrics::kMetricNetworkPhyModeSuffix[] = "PhyMode"; 76 const int Metrics::kMetricNetworkPhyModeMax = Metrics::kWiFiNetworkPhyModeMax; 77 const char Metrics::kMetricNetworkSecuritySuffix[] = "Security"; 78 const int Metrics::kMetricNetworkSecurityMax = Metrics::kWiFiSecurityMax; 79 const char Metrics::kMetricNetworkServiceErrors[] = 80 "Network.Shill.ServiceErrors"; 81 const char Metrics::kMetricNetworkSignalStrengthSuffix[] = "SignalStrength"; 82 const int Metrics::kMetricNetworkSignalStrengthMax = 200; 83 const int Metrics::kMetricNetworkSignalStrengthMin = 0; 84 const int Metrics::kMetricNetworkSignalStrengthNumBuckets = 40; 85 86 constexpr char 87 Metrics::kMetricRememberedSystemWiFiNetworkCountBySecurityModeFormat[]; 88 constexpr char 89 Metrics::kMetricRememberedUserWiFiNetworkCountBySecurityModeFormat[]; 90 91 const char Metrics::kMetricRememberedWiFiNetworkCount[] = 92 "Network.Shill.WiFi.RememberedNetworkCount"; 93 const int Metrics::kMetricRememberedWiFiNetworkCountMax = 1024; 94 const int Metrics::kMetricRememberedWiFiNetworkCountMin = 0; 95 const int Metrics::kMetricRememberedWiFiNetworkCountNumBuckets = 32; 96 97 const char Metrics::kMetricTimeOnlineSecondsSuffix[] = "TimeOnline"; 98 const int Metrics::kMetricTimeOnlineSecondsMax = 8 * 60 * 60; // 8 hours 99 const int Metrics::kMetricTimeOnlineSecondsMin = 1; 100 101 const char Metrics::kMetricTimeToConnectMillisecondsSuffix[] = "TimeToConnect"; 102 const int Metrics::kMetricTimeToConnectMillisecondsMax = 103 60 * 1000; // 60 seconds 104 const int Metrics::kMetricTimeToConnectMillisecondsMin = 1; 105 const int Metrics::kMetricTimeToConnectMillisecondsNumBuckets = 60; 106 107 const char Metrics::kMetricTimeToScanAndConnectMillisecondsSuffix[] = 108 "TimeToScanAndConnect"; 109 110 const char Metrics::kMetricTimeToDropSeconds[] = "Network.Shill.TimeToDrop";; 111 const int Metrics::kMetricTimeToDropSecondsMax = 8 * 60 * 60; // 8 hours 112 const int Metrics::kMetricTimeToDropSecondsMin = 1; 113 114 const char Metrics::kMetricTimeToDisableMillisecondsSuffix[] = "TimeToDisable"; 115 const int Metrics::kMetricTimeToDisableMillisecondsMax = 116 60 * 1000; // 60 seconds 117 const int Metrics::kMetricTimeToDisableMillisecondsMin = 1; 118 const int Metrics::kMetricTimeToDisableMillisecondsNumBuckets = 60; 119 120 const char Metrics::kMetricTimeToEnableMillisecondsSuffix[] = "TimeToEnable"; 121 const int Metrics::kMetricTimeToEnableMillisecondsMax = 122 60 * 1000; // 60 seconds 123 const int Metrics::kMetricTimeToEnableMillisecondsMin = 1; 124 const int Metrics::kMetricTimeToEnableMillisecondsNumBuckets = 60; 125 126 const char Metrics::kMetricTimeToInitializeMillisecondsSuffix[] = 127 "TimeToInitialize"; 128 const int Metrics::kMetricTimeToInitializeMillisecondsMax = 129 30 * 1000; // 30 seconds 130 const int Metrics::kMetricTimeToInitializeMillisecondsMin = 1; 131 const int Metrics::kMetricTimeToInitializeMillisecondsNumBuckets = 30; 132 133 const char Metrics::kMetricTimeResumeToReadyMillisecondsSuffix[] = 134 "TimeResumeToReady"; 135 const char Metrics::kMetricTimeToConfigMillisecondsSuffix[] = "TimeToConfig"; 136 const char Metrics::kMetricTimeToJoinMillisecondsSuffix[] = "TimeToJoin"; 137 const char Metrics::kMetricTimeToOnlineMillisecondsSuffix[] = "TimeToOnline"; 138 const char Metrics::kMetricTimeToPortalMillisecondsSuffix[] = "TimeToPortal"; 139 140 const char Metrics::kMetricTimeToScanMillisecondsSuffix[] = "TimeToScan"; 141 const int Metrics::kMetricTimeToScanMillisecondsMax = 180 * 1000; // 3 minutes 142 const int Metrics::kMetricTimeToScanMillisecondsMin = 1; 143 const int Metrics::kMetricTimeToScanMillisecondsNumBuckets = 90; 144 145 const int Metrics::kTimerHistogramMillisecondsMax = 45 * 1000; 146 const int Metrics::kTimerHistogramMillisecondsMin = 1; 147 const int Metrics::kTimerHistogramNumBuckets = 50; 148 149 const char Metrics::kMetricPortalAttemptsSuffix[] = "PortalAttempts"; 150 const int Metrics::kMetricPortalAttemptsMax = 151 PortalDetector::kMaxRequestAttempts; 152 const int Metrics::kMetricPortalAttemptsMin = 1; 153 const int Metrics::kMetricPortalAttemptsNumBuckets = 154 Metrics::kMetricPortalAttemptsMax; 155 156 const char Metrics::kMetricPortalAttemptsToOnlineSuffix[] = 157 "PortalAttemptsToOnline"; 158 const int Metrics::kMetricPortalAttemptsToOnlineMax = 100; 159 const int Metrics::kMetricPortalAttemptsToOnlineMin = 1; 160 const int Metrics::kMetricPortalAttemptsToOnlineNumBuckets = 10; 161 162 const char Metrics::kMetricPortalResultSuffix[] = "PortalResult"; 163 164 const char Metrics::kMetricFrequenciesConnectedEver[] = 165 "Network.Shill.WiFi.FrequenciesConnectedEver"; 166 const int Metrics::kMetricFrequenciesConnectedMax = 50; 167 const int Metrics::kMetricFrequenciesConnectedMin = 1; 168 const int Metrics::kMetricFrequenciesConnectedNumBuckets = 50; 169 170 const char Metrics::kMetricScanResult[] = 171 "Network.Shill.WiFi.ScanResult"; 172 const char Metrics::kMetricWiFiScanTimeInEbusyMilliseconds[] = 173 "Network.Shill.WiFi.ScanTimeInEbusy"; 174 175 const char Metrics::kMetricTerminationActionTimeTaken[] = 176 "Network.Shill.TerminationActionTimeTaken"; 177 const char Metrics::kMetricTerminationActionResult[] = 178 "Network.Shill.TerminationActionResult"; 179 const int Metrics::kMetricTerminationActionTimeTakenMillisecondsMax = 20000; 180 const int Metrics::kMetricTerminationActionTimeTakenMillisecondsMin = 1; 181 182 const char Metrics::kMetricSuspendActionTimeTaken[] = 183 "Network.Shill.SuspendActionTimeTaken"; 184 const char Metrics::kMetricSuspendActionResult[] = 185 "Network.Shill.SuspendActionResult"; 186 const int Metrics::kMetricSuspendActionTimeTakenMillisecondsMax = 20000; 187 const int Metrics::kMetricSuspendActionTimeTakenMillisecondsMin = 1; 188 189 const char Metrics::kMetricDarkResumeActionTimeTaken[] = 190 "Network.Shill.DarkResumeActionTimeTaken"; 191 const char Metrics::kMetricDarkResumeActionResult[] = 192 "Network.Shill.DarkResumeActionResult"; 193 const int Metrics::kMetricDarkResumeActionTimeTakenMillisecondsMax = 20000; 194 const int Metrics::kMetricDarkResumeActionTimeTakenMillisecondsMin = 1; 195 const char Metrics::kMetricDarkResumeUnmatchedScanResultReceived[] = 196 "Network.Shill.WiFi.DarkResumeUnmatchedScanResultsReceived"; 197 198 const char Metrics::kMetricWakeOnWiFiFeaturesEnabledState[] = 199 "Network.Shill.WiFi.WakeOnWiFiFeaturesEnabledState"; 200 const char Metrics::kMetricVerifyWakeOnWiFiSettingsResult[] = 201 "Network.Shill.WiFi.VerifyWakeOnWiFiSettingsResult"; 202 const char Metrics::kMetricWiFiConnectionStatusAfterWake[] = 203 "Network.Shill.WiFi.WiFiConnectionStatusAfterWake"; 204 const char Metrics::kMetricWakeOnWiFiThrottled[] = 205 "Network.Shill.WiFi.WakeOnWiFiThrottled"; 206 const char Metrics::kMetricWakeReasonReceivedBeforeOnDarkResume[] = 207 "Network.Shill.WiFi.WakeReasonReceivedBeforeOnDarkResume"; 208 const char Metrics::kMetricDarkResumeWakeReason[] = 209 "Network.Shill.WiFi.DarkResumeWakeReason"; 210 const char Metrics::kMetricDarkResumeScanType[] = 211 "Network.Shill.WiFi.DarkResumeScanType"; 212 const char Metrics::kMetricDarkResumeScanRetryResult[] = 213 "Network.Shill.WiFi.DarkResumeScanRetryResult"; 214 const char Metrics::kMetricDarkResumeScanNumRetries[] = 215 "Network.Shill.WiFi.DarkResumeScanNumRetries"; 216 const int Metrics::kMetricDarkResumeScanNumRetriesMax = 20; 217 const int Metrics::kMetricDarkResumeScanNumRetriesMin = 0; 218 219 // static 220 const char Metrics::kMetricServiceFixupEntriesSuffix[] = "ServiceFixupEntries"; 221 222 // static 223 const uint16_t Metrics::kWiFiBandwidth5MHz = 5; 224 const uint16_t Metrics::kWiFiBandwidth20MHz = 20; 225 const uint16_t Metrics::kWiFiFrequency2412 = 2412; 226 const uint16_t Metrics::kWiFiFrequency2472 = 2472; 227 const uint16_t Metrics::kWiFiFrequency2484 = 2484; 228 const uint16_t Metrics::kWiFiFrequency5170 = 5170; 229 const uint16_t Metrics::kWiFiFrequency5180 = 5180; 230 const uint16_t Metrics::kWiFiFrequency5230 = 5230; 231 const uint16_t Metrics::kWiFiFrequency5240 = 5240; 232 const uint16_t Metrics::kWiFiFrequency5320 = 5320; 233 const uint16_t Metrics::kWiFiFrequency5500 = 5500; 234 const uint16_t Metrics::kWiFiFrequency5700 = 5700; 235 const uint16_t Metrics::kWiFiFrequency5745 = 5745; 236 const uint16_t Metrics::kWiFiFrequency5825 = 5825; 237 238 // static 239 const char Metrics::kMetricPowerManagerKey[] = "metrics"; 240 241 // static 242 const char Metrics::kMetricLinkMonitorFailureSuffix[] = "LinkMonitorFailure"; 243 const char Metrics::kMetricLinkMonitorResponseTimeSampleSuffix[] = 244 "LinkMonitorResponseTimeSample"; 245 const int Metrics::kMetricLinkMonitorResponseTimeSampleMin = 0; 246 const int Metrics::kMetricLinkMonitorResponseTimeSampleMax = 247 LinkMonitor::kDefaultTestPeriodMilliseconds; 248 const int Metrics::kMetricLinkMonitorResponseTimeSampleNumBuckets = 50; 249 const char Metrics::kMetricLinkMonitorSecondsToFailureSuffix[] = 250 "LinkMonitorSecondsToFailure"; 251 const int Metrics::kMetricLinkMonitorSecondsToFailureMin = 0; 252 const int Metrics::kMetricLinkMonitorSecondsToFailureMax = 7200; 253 const int Metrics::kMetricLinkMonitorSecondsToFailureNumBuckets = 50; 254 const char Metrics::kMetricLinkMonitorBroadcastErrorsAtFailureSuffix[] = 255 "LinkMonitorBroadcastErrorsAtFailure"; 256 const char Metrics::kMetricLinkMonitorUnicastErrorsAtFailureSuffix[] = 257 "LinkMonitorUnicastErrorsAtFailure"; 258 const int Metrics::kMetricLinkMonitorErrorCountMin = 0; 259 const int Metrics::kMetricLinkMonitorErrorCountMax = 260 LinkMonitor::kFailureThreshold; 261 const int Metrics::kMetricLinkMonitorErrorCountNumBuckets = 262 LinkMonitor::kFailureThreshold + 1; 263 264 // static 265 const char Metrics::kMetricLinkClientDisconnectReason[] = 266 "Network.Shill.WiFi.ClientDisconnectReason"; 267 const char Metrics::kMetricLinkApDisconnectReason[] = 268 "Network.Shill.WiFi.ApDisconnectReason"; 269 const char Metrics::kMetricLinkClientDisconnectType[] = 270 "Network.Shill.WiFi.ClientDisconnectType"; 271 const char Metrics::kMetricLinkApDisconnectType[] = 272 "Network.Shill.WiFi.ApDisconnectType"; 273 274 // static 275 const char Metrics::kMetricCellular3GPPRegistrationDelayedDrop[] = 276 "Network.Shill.Cellular.3GPPRegistrationDelayedDrop"; 277 const char Metrics::kMetricCellularAutoConnectTries[] = 278 "Network.Shill.Cellular.AutoConnectTries"; 279 const int Metrics::kMetricCellularAutoConnectTriesMax = 20; 280 const int Metrics::kMetricCellularAutoConnectTriesMin = 1; 281 const int Metrics::kMetricCellularAutoConnectTriesNumBuckets = 20; 282 const char Metrics::kMetricCellularAutoConnectTotalTime[] = 283 "Network.Shill.Cellular.AutoConnectTotalTime"; 284 const int Metrics::kMetricCellularAutoConnectTotalTimeMax = 285 60 * 1000; // 60 seconds 286 const int Metrics::kMetricCellularAutoConnectTotalTimeMin = 0; 287 const int Metrics::kMetricCellularAutoConnectTotalTimeNumBuckets = 60; 288 const char Metrics::kMetricCellularDrop[] = 289 "Network.Shill.Cellular.Drop"; 290 291 // static 292 const char Metrics::kMetricCellularFailure[] = 293 "Network.Shill.Cellular.Failure"; 294 const int Metrics::kMetricCellularConnectionFailure = 0; 295 const int Metrics::kMetricCellularDisconnectionFailure = 1; 296 const int Metrics::kMetricCellularMaxFailure = 297 kMetricCellularDisconnectionFailure + 1; 298 299 const char Metrics::kMetricCellularOutOfCreditsReason[] = 300 "Network.Shill.Cellular.OutOfCreditsReason"; 301 const char Metrics::kMetricCellularSignalStrengthBeforeDrop[] = 302 "Network.Shill.Cellular.SignalStrengthBeforeDrop"; 303 const int Metrics::kMetricCellularSignalStrengthBeforeDropMax = 100; 304 const int Metrics::kMetricCellularSignalStrengthBeforeDropMin = 0; 305 const int Metrics::kMetricCellularSignalStrengthBeforeDropNumBuckets = 10; 306 307 // static 308 const char Metrics::kMetricCorruptedProfile[] = 309 "Network.Shill.CorruptedProfile"; 310 311 // static 312 const char Metrics::kMetricVpnDriver[] = 313 "Network.Shill.Vpn.Driver"; 314 const int Metrics::kMetricVpnDriverMax = Metrics::kVpnDriverMax; 315 const char Metrics::kMetricVpnRemoteAuthenticationType[] = 316 "Network.Shill.Vpn.RemoteAuthenticationType"; 317 const int Metrics::kMetricVpnRemoteAuthenticationTypeMax = 318 Metrics::kVpnRemoteAuthenticationTypeMax; 319 const char Metrics::kMetricVpnUserAuthenticationType[] = 320 "Network.Shill.Vpn.UserAuthenticationType"; 321 const int Metrics::kMetricVpnUserAuthenticationTypeMax = 322 Metrics::kVpnUserAuthenticationTypeMax; 323 324 const char Metrics::kMetricExpiredLeaseLengthSecondsSuffix[] = 325 "ExpiredLeaseLengthSeconds"; 326 const int Metrics::kMetricExpiredLeaseLengthSecondsMax = 327 7 * 24 * 60 * 60; // 7 days 328 const int Metrics::kMetricExpiredLeaseLengthSecondsMin = 1; 329 const int Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets = 330 Metrics::kMetricExpiredLeaseLengthSecondsMax; 331 332 // static 333 const char Metrics::kMetricWifiAutoConnectableServices[] = 334 "Network.Shill.WiFi.AutoConnectableServices"; 335 const int Metrics::kMetricWifiAutoConnectableServicesMax = 50; 336 const int Metrics::kMetricWifiAutoConnectableServicesMin = 1; 337 const int Metrics::kMetricWifiAutoConnectableServicesNumBuckets = 10; 338 339 // static 340 const char Metrics::kMetricWifiAvailableBSSes[] = 341 "Network.Shill.WiFi.AvailableBSSesAtConnect"; 342 const int Metrics::kMetricWifiAvailableBSSesMax = 50; 343 const int Metrics::kMetricWifiAvailableBSSesMin = 1; 344 const int Metrics::kMetricWifiAvailableBSSesNumBuckets = 10; 345 346 // static 347 const char Metrics::kMetricWifiStoppedTxQueueReason[] = 348 "Network.Shill.WiFi.StoppedTxQueueReason"; 349 // Values are defined in mac80211_monitor.h. 350 351 // static 352 const char Metrics::kMetricWifiStoppedTxQueueLength[] = 353 "Network.Shill.WiFi.StoppedTxQueueLength"; 354 const int Metrics::kMetricWifiStoppedTxQueueLengthMax = 10000; 355 const int Metrics::kMetricWifiStoppedTxQueueLengthMin = 1; 356 const int Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets = 50; 357 358 // Number of services associated with currently connected network. 359 const char Metrics::kMetricServicesOnSameNetwork[] = 360 "Network.Shill.ServicesOnSameNetwork"; 361 const int Metrics::kMetricServicesOnSameNetworkMax = 20; 362 const int Metrics::kMetricServicesOnSameNetworkMin = 1; 363 const int Metrics::kMetricServicesOnSameNetworkNumBuckets = 10; 364 365 // static 366 const char Metrics::kMetricUserInitiatedEvents[] = 367 "Network.Shill.UserInitiatedEvents"; 368 369 // static 370 const char Metrics::kMetricWifiTxBitrate[] = 371 "Network.Shill.WiFi.TransmitBitrateMbps"; 372 const int Metrics::kMetricWifiTxBitrateMax = 7000; 373 const int Metrics::kMetricWifiTxBitrateMin = 1; 374 const int Metrics::kMetricWifiTxBitrateNumBuckets = 100; 375 376 // static 377 const char Metrics::kMetricWifiUserInitiatedConnectionResult[] = 378 "Network.Shill.WiFi.UserInitiatedConnectionResult"; 379 380 // static 381 const char Metrics::kMetricWifiUserInitiatedConnectionFailureReason[] = 382 "Network.Shill.WiFi.UserInitiatedConnectionFailureReason"; 383 384 // static 385 const char Metrics::kMetricFallbackDNSTestResultSuffix[] = 386 "FallbackDNSTestResult"; 387 388 // static 389 const char Metrics::kMetricNetworkProblemDetectedSuffix[] = 390 "NetworkProblemDetected"; 391 392 // static 393 const char Metrics::kMetricDeviceConnectionStatus[] = 394 "Network.Shill.DeviceConnectionStatus"; 395 396 // static 397 const char Metrics::kMetricDhcpClientStatus[] = 398 "Network.Shill.DHCPClientStatus"; 399 400 // static 401 const char Metrics::kMetricDhcpClientMTUValue[] = 402 "Network.Shill.DHCPClientMTUValue"; 403 const char Metrics::kMetricPPPMTUValue[] = "Network.Shill.PPPMTUValue"; 404 405 // static 406 const char Metrics::kMetricNetworkConnectionIPTypeSuffix[] = 407 "NetworkConnectionIPType"; 408 409 // static 410 const char Metrics::kMetricIPv6ConnectivityStatusSuffix[] = 411 "IPv6ConnectivityStatus"; 412 413 // static 414 const char Metrics::kMetricDevicePresenceStatusSuffix[] = 415 "DevicePresenceStatus"; 416 417 // static 418 const char Metrics::kMetricDeviceRemovedEvent[] = 419 "Network.Shill.DeviceRemovedEvent"; 420 421 // static 422 const char Metrics::kMetricConnectionDiagnosticsIssue[] = 423 "Network.Shill.ConnectionDiagnosticsIssue"; 424 425 // static 426 const char Metrics::kMetricUnreliableLinkSignalStrengthSuffix[] = 427 "UnreliableLinkSignalStrength"; 428 const int Metrics::kMetricSerivceSignalStrengthMin = 0; 429 const int Metrics::kMetricServiceSignalStrengthMax = 100; 430 const int Metrics::kMetricServiceSignalStrengthNumBuckets = 40; 431 432 Metrics::Metrics(EventDispatcher* dispatcher) 433 : dispatcher_(dispatcher), 434 library_(&metrics_library_), 435 last_default_technology_(Technology::kUnknown), 436 was_online_(false), 437 time_online_timer_(new chromeos_metrics::Timer), 438 time_to_drop_timer_(new chromeos_metrics::Timer), 439 time_resume_to_ready_timer_(new chromeos_metrics::Timer), 440 time_termination_actions_timer(new chromeos_metrics::Timer), 441 time_suspend_actions_timer(new chromeos_metrics::Timer), 442 time_dark_resume_actions_timer(new chromeos_metrics::Timer), 443 collect_bootstats_(true), 444 num_scan_results_expected_in_dark_resume_(0), 445 wake_on_wifi_throttled_(false), 446 wake_reason_received_(false), 447 dark_resume_scan_retries_(0) { 448 metrics_library_.Init(); 449 chromeos_metrics::TimerReporter::set_metrics_lib(library_); 450 } 451 452 Metrics::~Metrics() {} 453 454 // static 455 Metrics::WiFiChannel Metrics::WiFiFrequencyToChannel(uint16_t frequency) { 456 WiFiChannel channel = kWiFiChannelUndef; 457 if (kWiFiFrequency2412 <= frequency && frequency <= kWiFiFrequency2472) { 458 if (((frequency - kWiFiFrequency2412) % kWiFiBandwidth5MHz) == 0) 459 channel = static_cast<WiFiChannel>( 460 kWiFiChannel2412 + 461 (frequency - kWiFiFrequency2412) / kWiFiBandwidth5MHz); 462 } else if (frequency == kWiFiFrequency2484) { 463 channel = kWiFiChannel2484; 464 } else if (kWiFiFrequency5170 <= frequency && 465 frequency <= kWiFiFrequency5230) { 466 if ((frequency % kWiFiBandwidth20MHz) == 0) 467 channel = static_cast<WiFiChannel>( 468 kWiFiChannel5180 + 469 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz); 470 if ((frequency % kWiFiBandwidth20MHz) == 10) 471 channel = static_cast<WiFiChannel>( 472 kWiFiChannel5170 + 473 (frequency - kWiFiFrequency5170) / kWiFiBandwidth20MHz); 474 } else if (kWiFiFrequency5240 <= frequency && 475 frequency <= kWiFiFrequency5320) { 476 if (((frequency - kWiFiFrequency5180) % kWiFiBandwidth20MHz) == 0) 477 channel = static_cast<WiFiChannel>( 478 kWiFiChannel5180 + 479 (frequency - kWiFiFrequency5180) / kWiFiBandwidth20MHz); 480 } else if (kWiFiFrequency5500 <= frequency && 481 frequency <= kWiFiFrequency5700) { 482 if (((frequency - kWiFiFrequency5500) % kWiFiBandwidth20MHz) == 0) 483 channel = static_cast<WiFiChannel>( 484 kWiFiChannel5500 + 485 (frequency - kWiFiFrequency5500) / kWiFiBandwidth20MHz); 486 } else if (kWiFiFrequency5745 <= frequency && 487 frequency <= kWiFiFrequency5825) { 488 if (((frequency - kWiFiFrequency5745) % kWiFiBandwidth20MHz) == 0) 489 channel = static_cast<WiFiChannel>( 490 kWiFiChannel5745 + 491 (frequency - kWiFiFrequency5745) / kWiFiBandwidth20MHz); 492 } 493 CHECK(kWiFiChannelUndef <= channel && channel < kWiFiChannelMax); 494 495 if (channel == kWiFiChannelUndef) 496 LOG(WARNING) << "no mapping for frequency " << frequency; 497 else 498 SLOG(nullptr, 3) << "mapped frequency " << frequency 499 << " to enum bucket " << channel; 500 501 return channel; 502 } 503 504 // static 505 Metrics::WiFiSecurity Metrics::WiFiSecurityStringToEnum( 506 const string& security) { 507 if (security == kSecurityNone) { 508 return kWiFiSecurityNone; 509 } else if (security == kSecurityWep) { 510 return kWiFiSecurityWep; 511 } else if (security == kSecurityWpa) { 512 return kWiFiSecurityWpa; 513 } else if (security == kSecurityRsn) { 514 return kWiFiSecurityRsn; 515 } else if (security == kSecurity8021x) { 516 return kWiFiSecurity8021x; 517 } else if (security == kSecurityPsk) { 518 return kWiFiSecurityPsk; 519 } else { 520 return kWiFiSecurityUnknown; 521 } 522 } 523 524 // static 525 Metrics::WiFiApMode Metrics::WiFiApModeStringToEnum(const string& ap_mode) { 526 if (ap_mode == kModeManaged) { 527 return kWiFiApModeManaged; 528 } else if (ap_mode == kModeAdhoc) { 529 return kWiFiApModeAdHoc; 530 } else { 531 return kWiFiApModeUnknown; 532 } 533 } 534 535 // static 536 Metrics::EapOuterProtocol Metrics::EapOuterProtocolStringToEnum( 537 const string& outer) { 538 if (outer == kEapMethodPEAP) { 539 return kEapOuterProtocolPeap; 540 } else if (outer == kEapMethodTLS) { 541 return kEapOuterProtocolTls; 542 } else if (outer == kEapMethodTTLS) { 543 return kEapOuterProtocolTtls; 544 } else if (outer == kEapMethodLEAP) { 545 return kEapOuterProtocolLeap; 546 } else { 547 return kEapOuterProtocolUnknown; 548 } 549 } 550 551 // static 552 Metrics::EapInnerProtocol Metrics::EapInnerProtocolStringToEnum( 553 const string& inner) { 554 if (inner.empty()) { 555 return kEapInnerProtocolNone; 556 } else if (inner == kEapPhase2AuthPEAPMD5) { 557 return kEapInnerProtocolPeapMd5; 558 } else if (inner == kEapPhase2AuthPEAPMSCHAPV2) { 559 return kEapInnerProtocolPeapMschapv2; 560 } else if (inner == kEapPhase2AuthTTLSEAPMD5) { 561 return kEapInnerProtocolTtlsEapMd5; 562 } else if (inner == kEapPhase2AuthTTLSEAPMSCHAPV2) { 563 return kEapInnerProtocolTtlsEapMschapv2; 564 } else if (inner == kEapPhase2AuthTTLSMSCHAPV2) { 565 return kEapInnerProtocolTtlsMschapv2; 566 } else if (inner == kEapPhase2AuthTTLSMSCHAP) { 567 return kEapInnerProtocolTtlsMschap; 568 } else if (inner == kEapPhase2AuthTTLSPAP) { 569 return kEapInnerProtocolTtlsPap; 570 } else if (inner == kEapPhase2AuthTTLSCHAP) { 571 return kEapInnerProtocolTtlsChap; 572 } else { 573 return kEapInnerProtocolUnknown; 574 } 575 } 576 577 // static 578 Metrics::PortalResult Metrics::PortalDetectionResultToEnum( 579 const PortalDetector::Result& portal_result) { 580 DCHECK(portal_result.final); 581 PortalResult retval = kPortalResultUnknown; 582 ConnectivityTrial::Result result = portal_result.trial_result; 583 // The only time we should end a successful portal detection is when we're 584 // in the Content phase. If we end with kStatusSuccess in any other phase, 585 // then this indicates that something bad has happened. 586 switch (result.phase) { 587 case ConnectivityTrial::kPhaseDNS: 588 if (result.status == ConnectivityTrial::kStatusFailure) 589 retval = kPortalResultDNSFailure; 590 else if (result.status == ConnectivityTrial::kStatusTimeout) 591 retval = kPortalResultDNSTimeout; 592 else 593 LOG(DFATAL) << __func__ << ": Final result status " << result.status 594 << " is not allowed in the DNS phase"; 595 break; 596 597 case ConnectivityTrial::kPhaseConnection: 598 if (result.status == ConnectivityTrial::kStatusFailure) 599 retval = kPortalResultConnectionFailure; 600 else if (result.status == ConnectivityTrial::kStatusTimeout) 601 retval = kPortalResultConnectionTimeout; 602 else 603 LOG(DFATAL) << __func__ << ": Final result status " << result.status 604 << " is not allowed in the Connection phase"; 605 break; 606 607 case ConnectivityTrial::kPhaseHTTP: 608 if (result.status == ConnectivityTrial::kStatusFailure) 609 retval = kPortalResultHTTPFailure; 610 else if (result.status == ConnectivityTrial::kStatusTimeout) 611 retval = kPortalResultHTTPTimeout; 612 else 613 LOG(DFATAL) << __func__ << ": Final result status " << result.status 614 << " is not allowed in the HTTP phase"; 615 break; 616 617 case ConnectivityTrial::kPhaseContent: 618 if (result.status == ConnectivityTrial::kStatusSuccess) 619 retval = kPortalResultSuccess; 620 else if (result.status == ConnectivityTrial::kStatusFailure) 621 retval = kPortalResultContentFailure; 622 else if (result.status == ConnectivityTrial::kStatusTimeout) 623 retval = kPortalResultContentTimeout; 624 else 625 LOG(DFATAL) << __func__ << ": Final result status " << result.status 626 << " is not allowed in the Content phase"; 627 break; 628 629 case ConnectivityTrial::kPhaseUnknown: 630 retval = kPortalResultUnknown; 631 break; 632 633 default: 634 LOG(DFATAL) << __func__ << ": Invalid phase " << result.phase; 635 break; 636 } 637 638 return retval; 639 } 640 641 void Metrics::Start() { 642 SLOG(this, 2) << __func__; 643 } 644 645 void Metrics::Stop() { 646 SLOG(this, 2) << __func__; 647 } 648 649 void Metrics::RegisterService(const Service& service) { 650 SLOG(this, 2) << __func__; 651 LOG_IF(WARNING, ContainsKey(services_metrics_, &service)) 652 << "Repeatedly registering " << service.unique_name(); 653 shared_ptr<ServiceMetrics> service_metrics(new ServiceMetrics()); 654 services_metrics_[&service] = service_metrics; 655 InitializeCommonServiceMetrics(service); 656 } 657 658 void Metrics::DeregisterService(const Service& service) { 659 services_metrics_.erase(&service); 660 } 661 662 void Metrics::AddServiceStateTransitionTimer( 663 const Service& service, 664 const string& histogram_name, 665 Service::ConnectState start_state, 666 Service::ConnectState stop_state) { 667 SLOG(this, 2) << __func__ << ": adding " << histogram_name << " for " 668 << Service::ConnectStateToString(start_state) << " -> " 669 << Service::ConnectStateToString(stop_state); 670 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service); 671 if (it == services_metrics_.end()) { 672 SLOG(this, 1) << "service not found"; 673 DCHECK(false); 674 return; 675 } 676 ServiceMetrics* service_metrics = it->second.get(); 677 CHECK(start_state < stop_state); 678 chromeos_metrics::TimerReporter* timer = 679 new chromeos_metrics::TimerReporter(histogram_name, 680 kTimerHistogramMillisecondsMin, 681 kTimerHistogramMillisecondsMax, 682 kTimerHistogramNumBuckets); 683 service_metrics->timers.push_back(timer); // passes ownership. 684 service_metrics->start_on_state[start_state].push_back(timer); 685 service_metrics->stop_on_state[stop_state].push_back(timer); 686 } 687 688 void Metrics::NotifyDefaultServiceChanged(const Service* service) { 689 base::TimeDelta elapsed_seconds; 690 691 Technology::Identifier technology = (service) ? service->technology() : 692 Technology::kUnknown; 693 if (technology != last_default_technology_) { 694 if (last_default_technology_ != Technology::kUnknown) { 695 string histogram = GetFullMetricName(kMetricTimeOnlineSecondsSuffix, 696 last_default_technology_); 697 time_online_timer_->GetElapsedTime(&elapsed_seconds); 698 SendToUMA(histogram, 699 elapsed_seconds.InSeconds(), 700 kMetricTimeOnlineSecondsMin, 701 kMetricTimeOnlineSecondsMax, 702 kTimerHistogramNumBuckets); 703 } 704 last_default_technology_ = technology; 705 time_online_timer_->Start(); 706 } 707 708 // Ignore changes that are not online/offline transitions; e.g. 709 // switching between wired and wireless. TimeToDrop measures 710 // time online regardless of how we are connected. 711 if ((service == nullptr && !was_online_) || 712 (service != nullptr && was_online_)) 713 return; 714 715 if (service == nullptr) { 716 time_to_drop_timer_->GetElapsedTime(&elapsed_seconds); 717 SendToUMA(kMetricTimeToDropSeconds, 718 elapsed_seconds.InSeconds(), 719 kMetricTimeToDropSecondsMin, 720 kMetricTimeToDropSecondsMax, 721 kTimerHistogramNumBuckets); 722 } else { 723 time_to_drop_timer_->Start(); 724 } 725 726 was_online_ = (service != nullptr); 727 } 728 729 void Metrics::NotifyServiceStateChanged(const Service& service, 730 Service::ConnectState new_state) { 731 ServiceMetricsLookupMap::iterator it = services_metrics_.find(&service); 732 if (it == services_metrics_.end()) { 733 SLOG(this, 1) << "service not found"; 734 DCHECK(false); 735 return; 736 } 737 ServiceMetrics* service_metrics = it->second.get(); 738 UpdateServiceStateTransitionMetrics(service_metrics, new_state); 739 740 if (new_state == Service::kStateFailure) 741 SendServiceFailure(service); 742 743 #if !defined(__ANDROID__) 744 if (collect_bootstats_) { 745 bootstat_log(base::StringPrintf("network-%s-%s", 746 Technology::NameFromIdentifier( 747 service.technology()).c_str(), 748 service.GetStateString().c_str()).c_str()); 749 } 750 #endif // __ANDROID__ 751 752 if (new_state != Service::kStateConnected) 753 return; 754 755 base::TimeDelta time_resume_to_ready; 756 time_resume_to_ready_timer_->GetElapsedTime(&time_resume_to_ready); 757 time_resume_to_ready_timer_->Reset(); 758 service.SendPostReadyStateMetrics(time_resume_to_ready.InMilliseconds()); 759 } 760 761 string Metrics::GetFullMetricName(const char* metric_suffix, 762 Technology::Identifier technology_id) { 763 string technology = Technology::NameFromIdentifier(technology_id); 764 technology[0] = base::ToUpperASCII(technology[0]); 765 return base::StringPrintf("%s.%s.%s", kMetricPrefix, technology.c_str(), 766 metric_suffix); 767 } 768 769 void Metrics::NotifyServiceDisconnect(const Service& service) { 770 Technology::Identifier technology = service.technology(); 771 string histogram = GetFullMetricName(kMetricDisconnectSuffix, technology); 772 SendToUMA(histogram, 773 service.explicitly_disconnected(), 774 kMetricDisconnectMin, 775 kMetricDisconnectMax, 776 kMetricDisconnectNumBuckets); 777 } 778 779 void Metrics::NotifySignalAtDisconnect(const Service& service, 780 int16_t signal_strength) { 781 // Negate signal_strength (goes from dBm to -dBm) because the metrics don't 782 // seem to handle negative values well. Now everything's positive. 783 Technology::Identifier technology = service.technology(); 784 string histogram = GetFullMetricName(kMetricSignalAtDisconnectSuffix, 785 technology); 786 SendToUMA(histogram, 787 -signal_strength, 788 kMetricSignalAtDisconnectMin, 789 kMetricSignalAtDisconnectMax, 790 kMetricSignalAtDisconnectNumBuckets); 791 } 792 793 void Metrics::NotifySuspendDone() { 794 time_resume_to_ready_timer_->Start(); 795 } 796 797 void Metrics::NotifyWakeOnWiFiFeaturesEnabledState( 798 WakeOnWiFiFeaturesEnabledState state) { 799 SendEnumToUMA(kMetricWakeOnWiFiFeaturesEnabledState, state, 800 kWakeOnWiFiFeaturesEnabledStateMax); 801 } 802 803 void Metrics::NotifyVerifyWakeOnWiFiSettingsResult( 804 VerifyWakeOnWiFiSettingsResult result) { 805 SendEnumToUMA(kMetricVerifyWakeOnWiFiSettingsResult, result, 806 kVerifyWakeOnWiFiSettingsResultMax); 807 } 808 809 void Metrics::NotifyConnectedToServiceAfterWake( 810 WiFiConnectionStatusAfterWake status) { 811 SendEnumToUMA(kMetricWiFiConnectionStatusAfterWake, status, 812 kWiFiConnetionStatusAfterWakeMax); 813 } 814 815 void Metrics::NotifyTerminationActionsStarted() { 816 if (time_termination_actions_timer->HasStarted()) 817 return; 818 time_termination_actions_timer->Start(); 819 } 820 821 void Metrics::NotifyTerminationActionsCompleted(bool success) { 822 if (!time_termination_actions_timer->HasStarted()) 823 return; 824 825 TerminationActionResult result = success ? kTerminationActionResultSuccess 826 : kTerminationActionResultFailure; 827 828 base::TimeDelta elapsed_time; 829 time_termination_actions_timer->GetElapsedTime(&elapsed_time); 830 time_termination_actions_timer->Reset(); 831 string time_metric, result_metric; 832 time_metric = kMetricTerminationActionTimeTaken; 833 result_metric = kMetricTerminationActionResult; 834 835 SendToUMA(time_metric, 836 elapsed_time.InMilliseconds(), 837 kMetricTerminationActionTimeTakenMillisecondsMin, 838 kMetricTerminationActionTimeTakenMillisecondsMax, 839 kTimerHistogramNumBuckets); 840 841 SendEnumToUMA(result_metric, 842 result, 843 kTerminationActionResultMax); 844 } 845 846 void Metrics::NotifySuspendActionsStarted() { 847 if (time_suspend_actions_timer->HasStarted()) 848 return; 849 time_suspend_actions_timer->Start(); 850 wake_on_wifi_throttled_ = false; 851 } 852 853 void Metrics::NotifySuspendActionsCompleted(bool success) { 854 if (!time_suspend_actions_timer->HasStarted()) 855 return; 856 857 // Reset for next dark resume. 858 wake_reason_received_ = false; 859 860 SuspendActionResult result = 861 success ? kSuspendActionResultSuccess : kSuspendActionResultFailure; 862 863 base::TimeDelta elapsed_time; 864 time_suspend_actions_timer->GetElapsedTime(&elapsed_time); 865 time_suspend_actions_timer->Reset(); 866 string time_metric, result_metric; 867 time_metric = kMetricSuspendActionTimeTaken; 868 result_metric = kMetricSuspendActionResult; 869 870 SendToUMA(time_metric, 871 elapsed_time.InMilliseconds(), 872 kMetricSuspendActionTimeTakenMillisecondsMin, 873 kMetricSuspendActionTimeTakenMillisecondsMax, 874 kTimerHistogramNumBuckets); 875 876 SendEnumToUMA(result_metric, 877 result, 878 kSuspendActionResultMax); 879 } 880 881 void Metrics::NotifyDarkResumeActionsStarted() { 882 if (time_dark_resume_actions_timer->HasStarted()) 883 return; 884 time_dark_resume_actions_timer->Start(); 885 num_scan_results_expected_in_dark_resume_ = 0; 886 dark_resume_scan_retries_ = 0; 887 } 888 889 void Metrics::NotifyDarkResumeActionsCompleted(bool success) { 890 if (!time_dark_resume_actions_timer->HasStarted()) 891 return; 892 893 // Reset for next dark resume. 894 wake_reason_received_ = false; 895 896 DarkResumeActionResult result = 897 success ? kDarkResumeActionResultSuccess : kDarkResumeActionResultFailure; 898 899 base::TimeDelta elapsed_time; 900 time_dark_resume_actions_timer->GetElapsedTime(&elapsed_time); 901 time_dark_resume_actions_timer->Reset(); 902 903 SendToUMA(kMetricDarkResumeActionTimeTaken, 904 elapsed_time.InMilliseconds(), 905 kMetricDarkResumeActionTimeTakenMillisecondsMin, 906 kMetricDarkResumeActionTimeTakenMillisecondsMax, 907 kTimerHistogramNumBuckets); 908 909 SendEnumToUMA(kMetricDarkResumeActionResult, 910 result, 911 kDarkResumeActionResultMax); 912 913 DarkResumeUnmatchedScanResultReceived unmatched_scan_results_received = 914 (num_scan_results_expected_in_dark_resume_ < 0) 915 ? kDarkResumeUnmatchedScanResultsReceivedTrue 916 : kDarkResumeUnmatchedScanResultsReceivedFalse; 917 SendEnumToUMA(kMetricDarkResumeUnmatchedScanResultReceived, 918 unmatched_scan_results_received, 919 kDarkResumeUnmatchedScanResultsReceivedMax); 920 921 SendToUMA(kMetricDarkResumeScanNumRetries, dark_resume_scan_retries_, 922 kMetricDarkResumeScanNumRetriesMin, 923 kMetricDarkResumeScanNumRetriesMax, kTimerHistogramNumBuckets); 924 } 925 926 void Metrics::NotifyDarkResumeInitiateScan() { 927 ++num_scan_results_expected_in_dark_resume_; 928 } 929 930 void Metrics::NotifyDarkResumeScanResultsReceived() { 931 --num_scan_results_expected_in_dark_resume_; 932 } 933 934 void Metrics::NotifyLinkMonitorFailure( 935 Technology::Identifier technology, 936 LinkMonitorFailure failure, 937 int seconds_to_failure, 938 int broadcast_error_count, 939 int unicast_error_count) { 940 string histogram = GetFullMetricName(kMetricLinkMonitorFailureSuffix, 941 technology); 942 SendEnumToUMA(histogram, failure, kLinkMonitorFailureMax); 943 944 if (failure == kLinkMonitorFailureThresholdReached) { 945 if (seconds_to_failure > kMetricLinkMonitorSecondsToFailureMax) { 946 seconds_to_failure = kMetricLinkMonitorSecondsToFailureMax; 947 } 948 histogram = GetFullMetricName(kMetricLinkMonitorSecondsToFailureSuffix, 949 technology); 950 SendToUMA(histogram, 951 seconds_to_failure, 952 kMetricLinkMonitorSecondsToFailureMin, 953 kMetricLinkMonitorSecondsToFailureMax, 954 kMetricLinkMonitorSecondsToFailureNumBuckets); 955 histogram = GetFullMetricName( 956 kMetricLinkMonitorBroadcastErrorsAtFailureSuffix, technology); 957 SendToUMA(histogram, 958 broadcast_error_count, 959 kMetricLinkMonitorErrorCountMin, 960 kMetricLinkMonitorErrorCountMax, 961 kMetricLinkMonitorErrorCountNumBuckets); 962 histogram = GetFullMetricName( 963 kMetricLinkMonitorUnicastErrorsAtFailureSuffix, technology); 964 SendToUMA(histogram, 965 unicast_error_count, 966 kMetricLinkMonitorErrorCountMin, 967 kMetricLinkMonitorErrorCountMax, 968 kMetricLinkMonitorErrorCountNumBuckets); 969 } 970 } 971 972 void Metrics::NotifyLinkMonitorResponseTimeSampleAdded( 973 Technology::Identifier technology, 974 int response_time_milliseconds) { 975 string histogram = GetFullMetricName( 976 kMetricLinkMonitorResponseTimeSampleSuffix, technology); 977 SendToUMA(histogram, 978 response_time_milliseconds, 979 kMetricLinkMonitorResponseTimeSampleMin, 980 kMetricLinkMonitorResponseTimeSampleMax, 981 kMetricLinkMonitorResponseTimeSampleNumBuckets); 982 } 983 984 #if !defined(DISABLE_WIFI) 985 // TODO(zqiu): Change argument type from IEEE_80211::WiFiReasonCode to 986 // Metrics::WiFiStatusType, to remove dependency for IEEE_80211. 987 void Metrics::Notify80211Disconnect(WiFiDisconnectByWhom by_whom, 988 IEEE_80211::WiFiReasonCode reason) { 989 string metric_disconnect_reason; 990 string metric_disconnect_type; 991 WiFiStatusType type; 992 993 if (by_whom == kDisconnectedByAp) { 994 metric_disconnect_reason = kMetricLinkApDisconnectReason; 995 metric_disconnect_type = kMetricLinkApDisconnectType; 996 type = kStatusCodeTypeByAp; 997 } else { 998 metric_disconnect_reason = kMetricLinkClientDisconnectReason; 999 metric_disconnect_type = kMetricLinkClientDisconnectType; 1000 switch (reason) { 1001 case IEEE_80211::kReasonCodeSenderHasLeft: 1002 case IEEE_80211::kReasonCodeDisassociatedHasLeft: 1003 type = kStatusCodeTypeByUser; 1004 break; 1005 1006 case IEEE_80211::kReasonCodeInactivity: 1007 type = kStatusCodeTypeConsideredDead; 1008 break; 1009 1010 default: 1011 type = kStatusCodeTypeByClient; 1012 break; 1013 } 1014 } 1015 SendEnumToUMA(metric_disconnect_reason, reason, 1016 IEEE_80211::kStatusCodeMax); 1017 SendEnumToUMA(metric_disconnect_type, type, kStatusCodeTypeMax); 1018 } 1019 #endif // DISABLE_WIFI 1020 1021 void Metrics::RegisterDevice(int interface_index, 1022 Technology::Identifier technology) { 1023 SLOG(this, 2) << __func__ << ": " << interface_index; 1024 shared_ptr<DeviceMetrics> device_metrics(new DeviceMetrics); 1025 devices_metrics_[interface_index] = device_metrics; 1026 device_metrics->technology = technology; 1027 string histogram = GetFullMetricName( 1028 kMetricTimeToInitializeMillisecondsSuffix, technology); 1029 device_metrics->initialization_timer.reset( 1030 new chromeos_metrics::TimerReporter( 1031 histogram, 1032 kMetricTimeToInitializeMillisecondsMin, 1033 kMetricTimeToInitializeMillisecondsMax, 1034 kMetricTimeToInitializeMillisecondsNumBuckets)); 1035 device_metrics->initialization_timer->Start(); 1036 histogram = GetFullMetricName(kMetricTimeToEnableMillisecondsSuffix, 1037 technology); 1038 device_metrics->enable_timer.reset( 1039 new chromeos_metrics::TimerReporter( 1040 histogram, 1041 kMetricTimeToEnableMillisecondsMin, 1042 kMetricTimeToEnableMillisecondsMax, 1043 kMetricTimeToEnableMillisecondsNumBuckets)); 1044 histogram = GetFullMetricName(kMetricTimeToDisableMillisecondsSuffix, 1045 technology); 1046 device_metrics->disable_timer.reset( 1047 new chromeos_metrics::TimerReporter( 1048 histogram, 1049 kMetricTimeToDisableMillisecondsMin, 1050 kMetricTimeToDisableMillisecondsMax, 1051 kMetricTimeToDisableMillisecondsNumBuckets)); 1052 histogram = GetFullMetricName(kMetricTimeToScanMillisecondsSuffix, 1053 technology); 1054 device_metrics->scan_timer.reset( 1055 new chromeos_metrics::TimerReporter( 1056 histogram, 1057 kMetricTimeToScanMillisecondsMin, 1058 kMetricTimeToScanMillisecondsMax, 1059 kMetricTimeToScanMillisecondsNumBuckets)); 1060 histogram = GetFullMetricName(kMetricTimeToConnectMillisecondsSuffix, 1061 technology); 1062 device_metrics->connect_timer.reset( 1063 new chromeos_metrics::TimerReporter( 1064 histogram, 1065 kMetricTimeToConnectMillisecondsMin, 1066 kMetricTimeToConnectMillisecondsMax, 1067 kMetricTimeToConnectMillisecondsNumBuckets)); 1068 histogram = GetFullMetricName(kMetricTimeToScanAndConnectMillisecondsSuffix, 1069 technology); 1070 device_metrics->scan_connect_timer.reset( 1071 new chromeos_metrics::TimerReporter( 1072 histogram, 1073 kMetricTimeToScanMillisecondsMin, 1074 kMetricTimeToScanMillisecondsMax + 1075 kMetricTimeToConnectMillisecondsMax, 1076 kMetricTimeToScanMillisecondsNumBuckets + 1077 kMetricTimeToConnectMillisecondsNumBuckets)); 1078 device_metrics->auto_connect_timer.reset( 1079 new chromeos_metrics::TimerReporter( 1080 kMetricCellularAutoConnectTotalTime, 1081 kMetricCellularAutoConnectTotalTimeMin, 1082 kMetricCellularAutoConnectTotalTimeMax, 1083 kMetricCellularAutoConnectTotalTimeNumBuckets)); 1084 } 1085 1086 bool Metrics::IsDeviceRegistered(int interface_index, 1087 Technology::Identifier technology) { 1088 SLOG(this, 2) << __func__ << ": interface index: " << interface_index 1089 << ", technology: " << technology; 1090 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1091 if (device_metrics == nullptr) 1092 return false; 1093 // Make sure the device technologies match. 1094 return (technology == device_metrics->technology); 1095 } 1096 1097 void Metrics::DeregisterDevice(int interface_index) { 1098 SLOG(this, 2) << __func__ << ": interface index: " << interface_index; 1099 1100 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1101 if (device_metrics != nullptr) { 1102 NotifyDeviceRemovedEvent(device_metrics->technology); 1103 } 1104 1105 devices_metrics_.erase(interface_index); 1106 } 1107 1108 void Metrics::NotifyDeviceInitialized(int interface_index) { 1109 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1110 if (device_metrics == nullptr) 1111 return; 1112 if (!device_metrics->initialization_timer->Stop()) 1113 return; 1114 device_metrics->initialization_timer->ReportMilliseconds(); 1115 } 1116 1117 void Metrics::NotifyDeviceEnableStarted(int interface_index) { 1118 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1119 if (device_metrics == nullptr) 1120 return; 1121 device_metrics->enable_timer->Start(); 1122 } 1123 1124 void Metrics::NotifyDeviceEnableFinished(int interface_index) { 1125 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1126 if (device_metrics == nullptr) 1127 return; 1128 if (!device_metrics->enable_timer->Stop()) 1129 return; 1130 device_metrics->enable_timer->ReportMilliseconds(); 1131 } 1132 1133 void Metrics::NotifyDeviceDisableStarted(int interface_index) { 1134 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1135 if (device_metrics == nullptr) 1136 return; 1137 device_metrics->disable_timer->Start(); 1138 } 1139 1140 void Metrics::NotifyDeviceDisableFinished(int interface_index) { 1141 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1142 if (device_metrics == nullptr) 1143 return; 1144 if (!device_metrics->disable_timer->Stop()) 1145 return; 1146 device_metrics->disable_timer->ReportMilliseconds(); 1147 } 1148 1149 void Metrics::NotifyDeviceScanStarted(int interface_index) { 1150 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1151 if (device_metrics == nullptr) 1152 return; 1153 device_metrics->scan_timer->Start(); 1154 device_metrics->scan_connect_timer->Start(); 1155 } 1156 1157 void Metrics::NotifyDeviceScanFinished(int interface_index) { 1158 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1159 if (device_metrics == nullptr) 1160 return; 1161 if (!device_metrics->scan_timer->Stop()) 1162 return; 1163 // Don't send TimeToScan metrics if the elapsed time exceeds the max metrics 1164 // value. Huge scan times usually mean something's gone awry; for cellular, 1165 // for instance, this usually means that the modem is in an area without 1166 // service and we're not interested in this scenario. 1167 base::TimeDelta elapsed_time; 1168 device_metrics->scan_timer->GetElapsedTime(&elapsed_time); 1169 if (elapsed_time.InMilliseconds() <= kMetricTimeToScanMillisecondsMax) 1170 device_metrics->scan_timer->ReportMilliseconds(); 1171 } 1172 1173 void Metrics::ResetScanTimer(int interface_index) { 1174 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1175 if (device_metrics == nullptr) 1176 return; 1177 device_metrics->scan_timer->Reset(); 1178 } 1179 1180 void Metrics::NotifyDeviceConnectStarted(int interface_index, 1181 bool is_auto_connecting) { 1182 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1183 if (device_metrics == nullptr) 1184 return; 1185 device_metrics->connect_timer->Start(); 1186 1187 if (is_auto_connecting) { 1188 device_metrics->auto_connect_tries++; 1189 if (device_metrics->auto_connect_tries == 1) 1190 device_metrics->auto_connect_timer->Start(); 1191 } else { 1192 AutoConnectMetricsReset(device_metrics); 1193 } 1194 } 1195 1196 void Metrics::NotifyDeviceConnectFinished(int interface_index) { 1197 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1198 if (device_metrics == nullptr) 1199 return; 1200 if (!device_metrics->connect_timer->Stop()) 1201 return; 1202 device_metrics->connect_timer->ReportMilliseconds(); 1203 1204 if (device_metrics->auto_connect_tries > 0) { 1205 if (!device_metrics->auto_connect_timer->Stop()) 1206 return; 1207 base::TimeDelta elapsed_time; 1208 device_metrics->auto_connect_timer->GetElapsedTime(&elapsed_time); 1209 if (elapsed_time.InMilliseconds() > kMetricCellularAutoConnectTotalTimeMax) 1210 return; 1211 device_metrics->auto_connect_timer->ReportMilliseconds(); 1212 SendToUMA(kMetricCellularAutoConnectTries, 1213 device_metrics->auto_connect_tries, 1214 kMetricCellularAutoConnectTriesMin, 1215 kMetricCellularAutoConnectTriesMax, 1216 kMetricCellularAutoConnectTriesNumBuckets); 1217 AutoConnectMetricsReset(device_metrics); 1218 } 1219 1220 if (!device_metrics->scan_connect_timer->Stop()) 1221 return; 1222 device_metrics->scan_connect_timer->ReportMilliseconds(); 1223 } 1224 1225 void Metrics::ResetConnectTimer(int interface_index) { 1226 DeviceMetrics* device_metrics = GetDeviceMetrics(interface_index); 1227 if (device_metrics == nullptr) 1228 return; 1229 device_metrics->connect_timer->Reset(); 1230 device_metrics->scan_connect_timer->Reset(); 1231 } 1232 1233 void Metrics::Notify3GPPRegistrationDelayedDropPosted() { 1234 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop, 1235 kCellular3GPPRegistrationDelayedDropPosted, 1236 kCellular3GPPRegistrationDelayedDropMax); 1237 } 1238 1239 void Metrics::Notify3GPPRegistrationDelayedDropCanceled() { 1240 SendEnumToUMA(kMetricCellular3GPPRegistrationDelayedDrop, 1241 kCellular3GPPRegistrationDelayedDropCanceled, 1242 kCellular3GPPRegistrationDelayedDropMax); 1243 } 1244 1245 void Metrics::NotifyCellularDeviceDrop(const string& network_technology, 1246 uint16_t signal_strength) { 1247 SLOG(this, 2) << __func__ << ": " << network_technology 1248 << ", " << signal_strength; 1249 CellularDropTechnology drop_technology = kCellularDropTechnologyUnknown; 1250 if (network_technology == kNetworkTechnology1Xrtt) { 1251 drop_technology = kCellularDropTechnology1Xrtt; 1252 } else if (network_technology == kNetworkTechnologyEdge) { 1253 drop_technology = kCellularDropTechnologyEdge; 1254 } else if (network_technology == kNetworkTechnologyEvdo) { 1255 drop_technology = kCellularDropTechnologyEvdo; 1256 } else if (network_technology == kNetworkTechnologyGprs) { 1257 drop_technology = kCellularDropTechnologyGprs; 1258 } else if (network_technology == kNetworkTechnologyGsm) { 1259 drop_technology = kCellularDropTechnologyGsm; 1260 } else if (network_technology == kNetworkTechnologyHspa) { 1261 drop_technology = kCellularDropTechnologyHspa; 1262 } else if (network_technology == kNetworkTechnologyHspaPlus) { 1263 drop_technology = kCellularDropTechnologyHspaPlus; 1264 } else if (network_technology == kNetworkTechnologyLte) { 1265 drop_technology = kCellularDropTechnologyLte; 1266 } else if (network_technology == kNetworkTechnologyUmts) { 1267 drop_technology = kCellularDropTechnologyUmts; 1268 } 1269 SendEnumToUMA(kMetricCellularDrop, 1270 drop_technology, 1271 kCellularDropTechnologyMax); 1272 SendToUMA(kMetricCellularSignalStrengthBeforeDrop, 1273 signal_strength, 1274 kMetricCellularSignalStrengthBeforeDropMin, 1275 kMetricCellularSignalStrengthBeforeDropMax, 1276 kMetricCellularSignalStrengthBeforeDropNumBuckets); 1277 } 1278 1279 void Metrics::NotifyCellularDeviceConnectionFailure() { 1280 library_->SendEnumToUMA( 1281 kMetricCellularFailure, kMetricCellularConnectionFailure, 1282 kMetricCellularMaxFailure); 1283 } 1284 1285 void Metrics::NotifyCellularDeviceDisconnectionFailure() { 1286 library_->SendEnumToUMA( 1287 kMetricCellularFailure, kMetricCellularDisconnectionFailure, 1288 kMetricCellularMaxFailure); 1289 } 1290 1291 void Metrics::NotifyCellularOutOfCredits( 1292 Metrics::CellularOutOfCreditsReason reason) { 1293 SendEnumToUMA(kMetricCellularOutOfCreditsReason, 1294 reason, 1295 kCellularOutOfCreditsReasonMax); 1296 } 1297 1298 void Metrics::NotifyCorruptedProfile() { 1299 SendEnumToUMA(kMetricCorruptedProfile, 1300 kCorruptedProfile, 1301 kCorruptedProfileMax); 1302 } 1303 1304 void Metrics::NotifyWifiAutoConnectableServices(int num_services) { 1305 SendToUMA(kMetricWifiAutoConnectableServices, 1306 num_services, 1307 kMetricWifiAutoConnectableServicesMin, 1308 kMetricWifiAutoConnectableServicesMax, 1309 kMetricWifiAutoConnectableServicesNumBuckets); 1310 } 1311 1312 void Metrics::NotifyWifiAvailableBSSes(int num_bss) { 1313 SendToUMA(kMetricWifiAvailableBSSes, 1314 num_bss, 1315 kMetricWifiAvailableBSSesMin, 1316 kMetricWifiAvailableBSSesMax, 1317 kMetricWifiAvailableBSSesNumBuckets); 1318 } 1319 1320 void Metrics::NotifyServicesOnSameNetwork(int num_services) { 1321 SendToUMA(kMetricServicesOnSameNetwork, 1322 num_services, 1323 kMetricServicesOnSameNetworkMin, 1324 kMetricServicesOnSameNetworkMax, 1325 kMetricServicesOnSameNetworkNumBuckets); 1326 } 1327 1328 void Metrics::NotifyUserInitiatedEvent(int event) { 1329 SendEnumToUMA(kMetricUserInitiatedEvents, 1330 event, 1331 kUserInitiatedEventMax); 1332 } 1333 1334 void Metrics::NotifyWifiTxBitrate(int bitrate) { 1335 SendToUMA(kMetricWifiTxBitrate, 1336 bitrate, 1337 kMetricWifiTxBitrateMin, 1338 kMetricWifiTxBitrateMax, 1339 kMetricWifiTxBitrateNumBuckets); 1340 } 1341 1342 void Metrics::NotifyUserInitiatedConnectionResult(const string& name, 1343 int result) { 1344 SendEnumToUMA(name, 1345 result, 1346 kUserInitiatedConnectionResultMax); 1347 } 1348 1349 void Metrics::NotifyUserInitiatedConnectionFailureReason( 1350 const string& name, const Service::ConnectFailure failure) { 1351 UserInitiatedConnectionFailureReason reason; 1352 switch (failure) { 1353 case Service::kFailureBadPassphrase: 1354 reason = kUserInitiatedConnectionFailureReasonBadPassphrase; 1355 break; 1356 case Service::kFailureBadWEPKey: 1357 reason = kUserInitiatedConnectionFailureReasonBadWEPKey; 1358 break; 1359 case Service::kFailureConnect: 1360 reason = kUserInitiatedConnectionFailureReasonConnect; 1361 break; 1362 case Service::kFailureDHCP: 1363 reason = kUserInitiatedConnectionFailureReasonDHCP; 1364 break; 1365 case Service::kFailureDNSLookup: 1366 reason = kUserInitiatedConnectionFailureReasonDNSLookup; 1367 break; 1368 case Service::kFailureEAPAuthentication: 1369 reason = kUserInitiatedConnectionFailureReasonEAPAuthentication; 1370 break; 1371 case Service::kFailureEAPLocalTLS: 1372 reason = kUserInitiatedConnectionFailureReasonEAPLocalTLS; 1373 break; 1374 case Service::kFailureEAPRemoteTLS: 1375 reason = kUserInitiatedConnectionFailureReasonEAPRemoteTLS; 1376 break; 1377 case Service::kFailureOutOfRange: 1378 reason = kUserInitiatedConnectionFailureReasonOutOfRange; 1379 break; 1380 case Service::kFailurePinMissing: 1381 reason = kUserInitiatedConnectionFailureReasonPinMissing; 1382 break; 1383 default: 1384 reason = kUserInitiatedConnectionFailureReasonUnknown; 1385 break; 1386 } 1387 SendEnumToUMA(name, 1388 reason, 1389 kUserInitiatedConnectionFailureReasonMax); 1390 } 1391 1392 void Metrics::NotifyFallbackDNSTestResult(Technology::Identifier technology_id, 1393 int result) { 1394 string histogram = GetFullMetricName(kMetricFallbackDNSTestResultSuffix, 1395 technology_id); 1396 SendEnumToUMA(histogram, 1397 result, 1398 kFallbackDNSTestResultMax); 1399 } 1400 1401 void Metrics::NotifyNetworkProblemDetected(Technology::Identifier technology_id, 1402 int reason) { 1403 string histogram = GetFullMetricName(kMetricNetworkProblemDetectedSuffix, 1404 technology_id); 1405 SendEnumToUMA(histogram, 1406 reason, 1407 kNetworkProblemMax); 1408 } 1409 1410 void Metrics::NotifyDeviceConnectionStatus(ConnectionStatus status) { 1411 SendEnumToUMA(kMetricDeviceConnectionStatus, status, kConnectionStatusMax); 1412 } 1413 1414 void Metrics::NotifyDhcpClientStatus(DhcpClientStatus status) { 1415 SendEnumToUMA(kMetricDhcpClientStatus, status, kDhcpClientStatusMax); 1416 } 1417 1418 void Metrics::NotifyNetworkConnectionIPType( 1419 Technology::Identifier technology_id, NetworkConnectionIPType type) { 1420 string histogram = GetFullMetricName(kMetricNetworkConnectionIPTypeSuffix, 1421 technology_id); 1422 SendEnumToUMA(histogram, type, kNetworkConnectionIPTypeMax); 1423 } 1424 1425 void Metrics::NotifyIPv6ConnectivityStatus(Technology::Identifier technology_id, 1426 bool status) { 1427 string histogram = GetFullMetricName(kMetricIPv6ConnectivityStatusSuffix, 1428 technology_id); 1429 IPv6ConnectivityStatus ipv6_status = status ? kIPv6ConnectivityStatusYes 1430 : kIPv6ConnectivityStatusNo; 1431 SendEnumToUMA(histogram, ipv6_status, kIPv6ConnectivityStatusMax); 1432 } 1433 1434 void Metrics::NotifyDevicePresenceStatus(Technology::Identifier technology_id, 1435 bool status) { 1436 string histogram = GetFullMetricName(kMetricDevicePresenceStatusSuffix, 1437 technology_id); 1438 DevicePresenceStatus presence = status ? kDevicePresenceStatusYes 1439 : kDevicePresenceStatusNo; 1440 SendEnumToUMA(histogram, presence, kDevicePresenceStatusMax); 1441 } 1442 1443 void Metrics::NotifyDeviceRemovedEvent(Technology::Identifier technology_id) { 1444 DeviceTechnologyType type; 1445 switch (technology_id) { 1446 case Technology::kEthernet: 1447 type = kDeviceTechnologyTypeEthernet; 1448 break; 1449 case Technology::kWifi: 1450 type = kDeviceTechnologyTypeWifi; 1451 break; 1452 case Technology::kWiMax: 1453 type = kDeviceTechnologyTypeWimax; 1454 break; 1455 case Technology::kCellular: 1456 type = kDeviceTechnologyTypeCellular; 1457 break; 1458 default: 1459 type = kDeviceTechnologyTypeUnknown; 1460 break; 1461 } 1462 SendEnumToUMA(kMetricDeviceRemovedEvent, type, kDeviceTechnologyTypeMax); 1463 } 1464 1465 void Metrics::NotifyUnreliableLinkSignalStrength( 1466 Technology::Identifier technology_id, int signal_strength) { 1467 string histogram = GetFullMetricName( 1468 kMetricUnreliableLinkSignalStrengthSuffix, technology_id); 1469 SendToUMA(histogram, 1470 signal_strength, 1471 kMetricSerivceSignalStrengthMin, 1472 kMetricServiceSignalStrengthMax, 1473 kMetricServiceSignalStrengthNumBuckets); 1474 } 1475 1476 bool Metrics::SendEnumToUMA(const string& name, int sample, int max) { 1477 SLOG(this, 5) 1478 << "Sending enum " << name << " with value " << sample << "."; 1479 return library_->SendEnumToUMA(name, sample, max); 1480 } 1481 1482 bool Metrics::SendToUMA(const string& name, int sample, int min, int max, 1483 int num_buckets) { 1484 SLOG(this, 5) 1485 << "Sending metric " << name << " with value " << sample << "."; 1486 return library_->SendToUMA(name, sample, min, max, num_buckets); 1487 } 1488 1489 bool Metrics::SendSparseToUMA(const string& name, int sample) { 1490 SLOG(this, 5) 1491 << "Sending sparse metric " << name << " with value " << sample << "."; 1492 return library_->SendSparseToUMA(name, sample); 1493 } 1494 1495 void Metrics::NotifyWakeOnWiFiThrottled() { 1496 wake_on_wifi_throttled_ = true; 1497 } 1498 1499 void Metrics::NotifySuspendWithWakeOnWiFiEnabledDone() { 1500 WakeOnWiFiThrottled throttled_result = wake_on_wifi_throttled_ 1501 ? kWakeOnWiFiThrottledTrue 1502 : kWakeOnWiFiThrottledFalse; 1503 SendEnumToUMA(kMetricWakeOnWiFiThrottled, throttled_result, 1504 kWakeOnWiFiThrottledMax); 1505 } 1506 1507 void Metrics::NotifyWakeupReasonReceived() { wake_reason_received_ = true; } 1508 1509 #if !defined(DISABLE_WIFI) 1510 // TODO(zqiu): Change argument type from WakeOnWiFi::WakeOnWiFiTrigger to 1511 // Metrics::DarkResumeWakeReason, to remove the dependency for WakeOnWiFi. 1512 // to remove the dependency for WakeOnWiFi. 1513 void Metrics::NotifyWakeOnWiFiOnDarkResume( 1514 WakeOnWiFi::WakeOnWiFiTrigger reason) { 1515 WakeReasonReceivedBeforeOnDarkResume result = 1516 wake_reason_received_ ? kWakeReasonReceivedBeforeOnDarkResumeTrue 1517 : kWakeReasonReceivedBeforeOnDarkResumeFalse; 1518 1519 SendEnumToUMA(kMetricWakeReasonReceivedBeforeOnDarkResume, result, 1520 kWakeReasonReceivedBeforeOnDarkResumeMax); 1521 1522 DarkResumeWakeReason wake_reason; 1523 switch (reason) { 1524 case WakeOnWiFi::kWakeTriggerPattern: 1525 wake_reason = kDarkResumeWakeReasonPattern; 1526 break; 1527 case WakeOnWiFi::kWakeTriggerDisconnect: 1528 wake_reason = kDarkResumeWakeReasonDisconnect; 1529 break; 1530 case WakeOnWiFi::kWakeTriggerSSID: 1531 wake_reason = kDarkResumeWakeReasonSSID; 1532 break; 1533 case WakeOnWiFi::kWakeTriggerUnsupported: 1534 default: 1535 wake_reason = kDarkResumeWakeReasonUnsupported; 1536 break; 1537 } 1538 SendEnumToUMA(kMetricDarkResumeWakeReason, wake_reason, 1539 kDarkResumeWakeReasonMax); 1540 } 1541 #endif // DISABLE_WIFI 1542 1543 void Metrics::NotifyScanStartedInDarkResume(bool is_active_scan) { 1544 DarkResumeScanType scan_type = 1545 is_active_scan ? kDarkResumeScanTypeActive : kDarkResumeScanTypePassive; 1546 SendEnumToUMA(kMetricDarkResumeScanType, scan_type, kDarkResumeScanTypeMax); 1547 } 1548 1549 void Metrics::NotifyDarkResumeScanRetry() { 1550 ++dark_resume_scan_retries_; 1551 } 1552 1553 void Metrics::NotifyBeforeSuspendActions(bool is_connected, 1554 bool in_dark_resume) { 1555 if (in_dark_resume && dark_resume_scan_retries_) { 1556 DarkResumeScanRetryResult connect_result = 1557 is_connected ? kDarkResumeScanRetryResultConnected 1558 : kDarkResumeScanRetryResultNotConnected; 1559 SendEnumToUMA(kMetricDarkResumeScanRetryResult, connect_result, 1560 kDarkResumeScanRetryResultMax); 1561 } 1562 } 1563 1564 void Metrics::NotifyConnectionDiagnosticsIssue(const string& issue) { 1565 ConnectionDiagnosticsIssue issue_enum; 1566 if (issue == ConnectionDiagnostics::kIssueIPCollision) { 1567 issue_enum = kConnectionDiagnosticsIssueIPCollision; 1568 } else if (issue == ConnectionDiagnostics::kIssueRouting) { 1569 issue_enum = kConnectionDiagnosticsIssueRouting; 1570 } else if (issue == ConnectionDiagnostics::kIssueHTTPBrokenPortal) { 1571 issue_enum = kConnectionDiagnosticsIssueHTTPBrokenPortal; 1572 } else if (issue == ConnectionDiagnostics::kIssueDNSServerMisconfig) { 1573 issue_enum = kConnectionDiagnosticsIssueDNSServerMisconfig; 1574 } else if (issue == ConnectionDiagnostics::kIssueDNSServerNoResponse) { 1575 issue_enum = kConnectionDiagnosticsIssueDNSServerNoResponse; 1576 } else if (issue == ConnectionDiagnostics::kIssueNoDNSServersConfigured) { 1577 issue_enum = kConnectionDiagnosticsIssueNoDNSServersConfigured; 1578 } else if (issue == ConnectionDiagnostics::kIssueDNSServersInvalid) { 1579 issue_enum = kConnectionDiagnosticsIssueDNSServersInvalid; 1580 } else if (issue == ConnectionDiagnostics::kIssueNone) { 1581 issue_enum = kConnectionDiagnosticsIssueNone; 1582 } else if (issue == ConnectionDiagnostics::kIssueCaptivePortal) { 1583 issue_enum = kConnectionDiagnosticsIssueCaptivePortal; 1584 } else if (issue == ConnectionDiagnostics::kIssueGatewayUpstream) { 1585 issue_enum = kConnectionDiagnosticsIssueGatewayUpstream; 1586 } else if (issue == ConnectionDiagnostics::kIssueGatewayNotResponding) { 1587 issue_enum = kConnectionDiagnosticsIssueGatewayNotResponding; 1588 } else if (issue == ConnectionDiagnostics::kIssueServerNotResponding) { 1589 issue_enum = kConnectionDiagnosticsIssueServerNotResponding; 1590 } else if (issue == ConnectionDiagnostics::kIssueGatewayArpFailed) { 1591 issue_enum = kConnectionDiagnosticsIssueGatewayArpFailed; 1592 } else if (issue == ConnectionDiagnostics::kIssueServerArpFailed) { 1593 issue_enum = kConnectionDiagnosticsIssueServerArpFailed; 1594 } else if (issue == ConnectionDiagnostics::kIssueInternalError) { 1595 issue_enum = kConnectionDiagnosticsIssueInternalError; 1596 } else if (issue == ConnectionDiagnostics::kIssueGatewayNoNeighborEntry) { 1597 issue_enum = kConnectionDiagnosticsIssueGatewayNoNeighborEntry; 1598 } else if (issue == ConnectionDiagnostics::kIssueServerNoNeighborEntry) { 1599 issue_enum = kConnectionDiagnosticsIssueServerNoNeighborEntry; 1600 } else if (issue == 1601 ConnectionDiagnostics::kIssueGatewayNeighborEntryNotConnected) { 1602 issue_enum = kConnectionDiagnosticsIssueGatewayNeighborEntryNotConnected; 1603 } else if (issue == 1604 ConnectionDiagnostics::kIssueServerNeighborEntryNotConnected) { 1605 issue_enum = kConnectionDiagnosticsIssueServerNeighborEntryNotConnected; 1606 } else { 1607 LOG(ERROR) << __func__ << ": Invalid issue: " << issue; 1608 return; 1609 } 1610 1611 SendEnumToUMA(kMetricConnectionDiagnosticsIssue, issue_enum, 1612 kConnectionDiagnosticsIssueMax); 1613 } 1614 1615 void Metrics::InitializeCommonServiceMetrics(const Service& service) { 1616 Technology::Identifier technology = service.technology(); 1617 string histogram = GetFullMetricName(kMetricTimeToConfigMillisecondsSuffix, 1618 technology); 1619 AddServiceStateTransitionTimer( 1620 service, 1621 histogram, 1622 Service::kStateConfiguring, 1623 Service::kStateConnected); 1624 histogram = GetFullMetricName(kMetricTimeToPortalMillisecondsSuffix, 1625 technology); 1626 AddServiceStateTransitionTimer( 1627 service, 1628 histogram, 1629 Service::kStateConnected, 1630 Service::kStatePortal); 1631 histogram = GetFullMetricName(kMetricTimeToOnlineMillisecondsSuffix, 1632 technology); 1633 AddServiceStateTransitionTimer( 1634 service, 1635 histogram, 1636 Service::kStateConnected, 1637 Service::kStateOnline); 1638 } 1639 1640 void Metrics::UpdateServiceStateTransitionMetrics( 1641 ServiceMetrics* service_metrics, 1642 Service::ConnectState new_state) { 1643 const char* state_string = Service::ConnectStateToString(new_state); 1644 SLOG(this, 5) << __func__ << ": new_state=" << state_string; 1645 TimerReportersList& start_timers = service_metrics->start_on_state[new_state]; 1646 for (auto& start_timer : start_timers) { 1647 SLOG(this, 5) << "Starting timer for " << start_timer->histogram_name() 1648 << " due to new state " << state_string << "."; 1649 start_timer->Start(); 1650 } 1651 1652 TimerReportersList& stop_timers = service_metrics->stop_on_state[new_state]; 1653 for (auto& stop_timer : stop_timers) { 1654 SLOG(this, 5) << "Stopping timer for " << stop_timer->histogram_name() 1655 << " due to new state " << state_string << "."; 1656 if (stop_timer->Stop()) 1657 stop_timer->ReportMilliseconds(); 1658 } 1659 } 1660 1661 void Metrics::SendServiceFailure(const Service& service) { 1662 NetworkServiceError error = kNetworkServiceErrorUnknown; 1663 // Explicitly map all possible failures. So when new failures are added, 1664 // they will need to be mapped as well. Otherwise, the compiler will 1665 // complain. 1666 switch (service.failure()) { 1667 case Service::kFailureUnknown: 1668 case Service::kFailureMax: 1669 error = kNetworkServiceErrorUnknown; 1670 break; 1671 case Service::kFailureAAA: 1672 error = kNetworkServiceErrorAAA; 1673 break; 1674 case Service::kFailureActivation: 1675 error = kNetworkServiceErrorActivation; 1676 break; 1677 case Service::kFailureBadPassphrase: 1678 error = kNetworkServiceErrorBadPassphrase; 1679 break; 1680 case Service::kFailureBadWEPKey: 1681 error = kNetworkServiceErrorBadWEPKey; 1682 break; 1683 case Service::kFailureConnect: 1684 error = kNetworkServiceErrorConnect; 1685 break; 1686 case Service::kFailureDHCP: 1687 error = kNetworkServiceErrorDHCP; 1688 break; 1689 case Service::kFailureDNSLookup: 1690 error = kNetworkServiceErrorDNSLookup; 1691 break; 1692 case Service::kFailureEAPAuthentication: 1693 error = kNetworkServiceErrorEAPAuthentication; 1694 break; 1695 case Service::kFailureEAPLocalTLS: 1696 error = kNetworkServiceErrorEAPLocalTLS; 1697 break; 1698 case Service::kFailureEAPRemoteTLS: 1699 error = kNetworkServiceErrorEAPRemoteTLS; 1700 break; 1701 case Service::kFailureHTTPGet: 1702 error = kNetworkServiceErrorHTTPGet; 1703 break; 1704 case Service::kFailureIPSecCertAuth: 1705 error = kNetworkServiceErrorIPSecCertAuth; 1706 break; 1707 case Service::kFailureIPSecPSKAuth: 1708 error = kNetworkServiceErrorIPSecPSKAuth; 1709 break; 1710 case Service::kFailureInternal: 1711 error = kNetworkServiceErrorInternal; 1712 break; 1713 case Service::kFailureNeedEVDO: 1714 error = kNetworkServiceErrorNeedEVDO; 1715 break; 1716 case Service::kFailureNeedHomeNetwork: 1717 error = kNetworkServiceErrorNeedHomeNetwork; 1718 break; 1719 case Service::kFailureOTASP: 1720 error = kNetworkServiceErrorOTASP; 1721 break; 1722 case Service::kFailureOutOfRange: 1723 error = kNetworkServiceErrorOutOfRange; 1724 break; 1725 case Service::kFailurePPPAuth: 1726 error = kNetworkServiceErrorPPPAuth; 1727 break; 1728 case Service::kFailurePinMissing: 1729 error = kNetworkServiceErrorPinMissing; 1730 break; 1731 } 1732 1733 library_->SendEnumToUMA(kMetricNetworkServiceErrors, 1734 error, 1735 kNetworkServiceErrorMax); 1736 } 1737 1738 Metrics::DeviceMetrics* Metrics::GetDeviceMetrics(int interface_index) const { 1739 DeviceMetricsLookupMap::const_iterator it = 1740 devices_metrics_.find(interface_index); 1741 if (it == devices_metrics_.end()) { 1742 SLOG(this, 2) << __func__ << ": device " << interface_index 1743 << " not found"; 1744 return nullptr; 1745 } 1746 return it->second.get(); 1747 } 1748 1749 void Metrics::AutoConnectMetricsReset(DeviceMetrics* device_metrics) { 1750 device_metrics->auto_connect_tries = 0; 1751 device_metrics->auto_connect_timer->Reset(); 1752 } 1753 1754 void Metrics::set_library(MetricsLibraryInterface* library) { 1755 chromeos_metrics::TimerReporter::set_metrics_lib(library); 1756 library_ = library; 1757 } 1758 1759 } // namespace shill 1760