blob: 2aac1f148f1f98ffb312a3b29593684593dc3221 [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// 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#ifndef SHILL_METRICS_
6#define SHILL_METRICS_
7
8#include <list>
9
10#include <base/lazy_instance.h>
11#include <base/memory/scoped_vector.h>
12#include <metrics/metrics_library.h>
13#include <metrics/timer.h>
14
15#include "shill/refptr_types.h"
16#include "shill/service.h"
17
18namespace shill {
19
20class WiFiService;
21
22class Metrics {
23 public:
24 enum WiFiChannel {
25 kWiFiChannelUndef = 0,
26 kWiFiChannel2412 = 1,
27 kWiFiChannel2417 = 2,
28 kWiFiChannel2422 = 3,
29 kWiFiChannel2427 = 4,
30 kWiFiChannel2432 = 5,
31 kWiFiChannel2437 = 6,
32 kWiFiChannel2442 = 7,
33 kWiFiChannel2447 = 8,
34 kWiFiChannel2452 = 9,
35 kWiFiChannel2457 = 10,
36 kWiFiChannel2462 = 11,
37 kWiFiChannel2467 = 12,
38 kWiFiChannel2472 = 13,
39 kWiFiChannel2484 = 14,
40
41 kWiFiChannel5180 = 15,
42 kWiFiChannel5200 = 16,
43 kWiFiChannel5220 = 17,
44 kWiFiChannel5240 = 18,
45 kWiFiChannel5260 = 19,
46 kWiFiChannel5280 = 20,
47 kWiFiChannel5300 = 21,
48 kWiFiChannel5320 = 22,
49
50 kWiFiChannel5500 = 23,
51 kWiFiChannel5520 = 24,
52 kWiFiChannel5540 = 25,
53 kWiFiChannel5560 = 26,
54 kWiFiChannel5580 = 27,
55 kWiFiChannel5600 = 28,
56 kWiFiChannel5620 = 29,
57 kWiFiChannel5640 = 30,
58 kWiFiChannel5660 = 31,
59 kWiFiChannel5680 = 32,
60 kWiFiChannel5700 = 33,
61
62 kWiFiChannel5745 = 34,
63 kWiFiChannel5765 = 35,
64 kWiFiChannel5785 = 36,
65 kWiFiChannel5805 = 37,
66 kWiFiChannel5825 = 38,
67
68 kWiFiChannel5170 = 39,
69 kWiFiChannel5190 = 40,
70 kWiFiChannel5210 = 41,
71 kWiFiChannel5230 = 42,
72
73 /* NB: ignore old 11b bands 2312..2372 and 2512..2532 */
74 /* NB: ignore regulated bands 4920..4980 and 5020..5160 */
75 kWiFiChannelMax
76 };
77
Thieu Lead1ec2c2012-01-05 23:39:48 +000078 enum WiFiNetworkPhyMode {
79 kWiFiNetworkPhyModeUndef = 0, // Unknown/undefined
80 kWiFiNetworkPhyMode11a = 1, // 802.11a
81 kWiFiNetworkPhyMode11b = 2, // 802.11b
82 kWiFiNetworkPhyMode11g = 3, // 802.11g
83 kWiFiNetworkPhyMode11n = 4, // 802.11n
84 kWiFiNetworkPhyModeHalf = 5, // PSB Half-width
85 kWiFiNetworkPhyModeQuarter = 6, // PSB Quarter-width
86 kWiFiNetworkPhyModeTurbo = 7, // Atheros Turbo mode
87
88 kWiFiNetworkPhyModeMax
89 };
90
91 enum WiFiSecurity {
92 kWiFiSecurityUnknown = 0,
93 kWiFiSecurityNone = 1,
94 kWiFiSecurityWep = 2,
95 kWiFiSecurityWpa = 3,
96 kWiFiSecurityRsn = 4,
97 kWiFiSecurity8021x = 5,
98 kWiFiSecurityPsk = 6,
99
100 kWiFiSecurityMax
101 };
102
Thieu Le67370f62012-02-14 23:01:42 +0000103 static const char kMetricDisconnect[];
104 static const int kMetricDisconnectMax;
105 static const int kMetricDisconnectMin;
106 static const int kMetricDisconnectNumBuckets;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000107 static const char kMetricNetworkChannel[];
108 static const int kMetricNetworkChannelMax;
Thieu Lead1ec2c2012-01-05 23:39:48 +0000109 static const char kMetricNetworkPhyMode[];
110 static const int kMetricNetworkPhyModeMax;
111 static const char kMetricNetworkSecurity[];
112 static const int kMetricNetworkSecurityMax;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000113 static const char kMetricNetworkServiceErrors[];
114 static const int kMetricNetworkServiceErrorsMax;
Thieu Lea20cbc22012-01-09 22:01:43 +0000115 static const char kMetricTimeOnlineSeconds[];
116 static const int kMetricTimeOnlineSecondsMax;
117 static const int kMetricTimeOnlineSecondsMin;
118 static const int kMetricTimeOnlineSecondsNumBuckets;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000119 static const char kMetricTimeToConfigMilliseconds[];
Thieu Lea20cbc22012-01-09 22:01:43 +0000120 static const char kMetricTimeToDropSeconds[];
121 static const int kMetricTimeToDropSecondsMax;
122 static const int kMetricTimeToDropSecondsMin;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000123 static const char kMetricTimeToJoinMilliseconds[];
124 static const char kMetricTimeToOnlineMilliseconds[];
125 static const char kMetricTimeToPortalMilliseconds[];
Thieu Lea20cbc22012-01-09 22:01:43 +0000126 static const int kTimerHistogramMillisecondsMax;
127 static const int kTimerHistogramMillisecondsMin;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000128 static const int kTimerHistogramNumBuckets;
129
Thieu Le3426c8f2012-01-11 17:35:11 -0800130 Metrics();
Thieu Le48e6d6d2011-12-06 00:40:27 +0000131 virtual ~Metrics();
132
Thieu Le48e6d6d2011-12-06 00:40:27 +0000133 // Converts the WiFi frequency into the associated UMA channel enumerator.
134 static WiFiChannel WiFiFrequencyToChannel(uint16 frequency);
135
Thieu Lead1ec2c2012-01-05 23:39:48 +0000136 // Converts a flimflam security string into its UMA security enumerator.
137 static WiFiSecurity WiFiSecurityStringToEnum(const std::string &security);
138
Thieu Le48e6d6d2011-12-06 00:40:27 +0000139 // Registers a service with this object so it can use the timers to track
140 // state transition metrics.
141 void RegisterService(const Service *service);
142
143 // Deregisters the service from this class. All state transition timers
144 // will be removed.
145 void DeregisterService(const Service *service);
146
147 // Tracks the time it takes |service| to go from |start_state| to
148 // |stop_state|. When |stop_state| is reached, the time is sent to UMA.
149 void AddServiceStateTransitionTimer(const Service *service,
150 const std::string &histogram_name,
151 Service::ConnectState start_state,
152 Service::ConnectState stop_state);
153
154 // Specializes |metric_name| for the specified |technology_id|.
155 std::string GetFullMetricName(const char *metric_name,
156 Technology::Identifier technology_id);
157
158 // Notifies this object that the default service has changed.
159 // |service| is the new default service.
Thieu Lea20cbc22012-01-09 22:01:43 +0000160 virtual void NotifyDefaultServiceChanged(const Service *service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000161
162 // Notifies this object that |service| state has changed.
163 virtual void NotifyServiceStateChanged(const Service *service,
164 Service::ConnectState new_state);
165
Thieu Le67370f62012-02-14 23:01:42 +0000166 // Notifies this object that |service| has been disconnected.
167 void NotifyServiceDisconnect(const Service *service);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000168
169 // Notifies this object of a power management event.
170 void NotifyPower();
171
172 // Sends linear histogram data to UMA.
173 bool SendEnumToUMA(const std::string &name, int sample, int max);
174
Thieu Lea20cbc22012-01-09 22:01:43 +0000175 // Send histogram data to UMA.
176 bool SendToUMA(const std::string &name, int sample, int min, int max,
177 int num_buckets);
178
Thieu Le48e6d6d2011-12-06 00:40:27 +0000179 private:
180 friend struct base::DefaultLazyInstanceTraits<Metrics>;
181 friend class MetricsTest;
182 FRIEND_TEST(MetricsTest, TimeToConfig);
183 FRIEND_TEST(MetricsTest, TimeToPortal);
184 FRIEND_TEST(MetricsTest, TimeToOnline);
185 FRIEND_TEST(MetricsTest, ServiceFailure);
186 FRIEND_TEST(MetricsTest, WiFiServiceChannel);
187 FRIEND_TEST(MetricsTest, FrequencyToChannel);
Thieu Lea20cbc22012-01-09 22:01:43 +0000188 FRIEND_TEST(MetricsTest, TimeOnlineTimeToDrop);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000189
190 typedef ScopedVector<chromeos_metrics::TimerReporter> TimerReporters;
191 typedef std::list<chromeos_metrics::TimerReporter *> TimerReportersList;
192 typedef std::map<Service::ConnectState, TimerReportersList>
193 TimerReportersByState;
194 struct ServiceMetrics {
195 ServiceMetrics() : service(NULL) {}
196 // The service is registered/deregistered in the Service
197 // constructor/destructor, therefore there is no need to keep a ref count.
198 const Service *service;
199 // All TimerReporter objects are stored in |timers| which owns the objects.
200 // |start_on_state| and |stop_on_state| contain pointers to the
201 // TimerReporter objects and control when to start and stop the timers.
202 TimerReporters timers;
203 TimerReportersByState start_on_state;
204 TimerReportersByState stop_on_state;
205 };
206 typedef std::map<const Service *, std::tr1::shared_ptr<ServiceMetrics> >
207 ServiceMetricsLookupMap;
208
209 static const uint16 kWiFiBandwidth5MHz;
210 static const uint16 kWiFiBandwidth20MHz;
211 static const uint16 kWiFiFrequency2412;
212 static const uint16 kWiFiFrequency2472;
213 static const uint16 kWiFiFrequency2484;
214 static const uint16 kWiFiFrequency5170;
215 static const uint16 kWiFiFrequency5180;
216 static const uint16 kWiFiFrequency5230;
217 static const uint16 kWiFiFrequency5240;
218 static const uint16 kWiFiFrequency5320;
219 static const uint16 kWiFiFrequency5500;
220 static const uint16 kWiFiFrequency5700;
221 static const uint16 kWiFiFrequency5745;
222 static const uint16 kWiFiFrequency5825;
223
Thieu Le48e6d6d2011-12-06 00:40:27 +0000224 void InitializeCommonServiceMetrics(const Service *service);
225 void UpdateServiceStateTransitionMetrics(ServiceMetrics *service_metrics,
226 Service::ConnectState new_state);
227 void SendServiceFailure(const Service *service);
228
229 // For unit test purposes.
230 void set_library(MetricsLibraryInterface *library);
Thieu Lea20cbc22012-01-09 22:01:43 +0000231 void set_time_online_timer(chromeos_metrics::Timer *timer) {
232 time_online_timer_.reset(timer); // Passes ownership
233 }
234 void set_time_to_drop_timer(chromeos_metrics::Timer *timer) {
235 time_to_drop_timer_.reset(timer); // Passes ownership
236 }
Thieu Le48e6d6d2011-12-06 00:40:27 +0000237
238 // |library_| points to |metrics_library_| when shill runs normally.
239 // However, in order to allow for unit testing, we point |library_| to a
240 // MetricsLibraryMock object instead.
241 MetricsLibrary metrics_library_;
242 MetricsLibraryInterface *library_;
243 ServiceMetricsLookupMap services_metrics_;
Thieu Lea20cbc22012-01-09 22:01:43 +0000244 Technology::Identifier last_default_technology_;
245 bool was_online_;
246 scoped_ptr<chromeos_metrics::Timer> time_online_timer_;
247 scoped_ptr<chromeos_metrics::Timer> time_to_drop_timer_;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000248
249 DISALLOW_COPY_AND_ASSIGN(Metrics);
250};
251
252} // namespace shill
253
254#endif // SHILL_METRICS_