| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/base/network_change_notifier.h" | |
| 6 | |
| 7 #include <limits> | |
| 8 | |
| 9 #include "base/metrics/histogram.h" | |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "base/threading/thread_checker.h" | |
| 12 #include "build/build_config.h" | |
| 13 #include "net/base/net_util.h" | |
| 14 #include "net/base/network_change_notifier_factory.h" | |
| 15 #include "net/dns/dns_config_service.h" | |
| 16 #include "net/url_request/url_request.h" | |
| 17 #include "url/gurl.h" | |
| 18 | |
| 19 #if defined(OS_ANDROID) | |
| 20 #include "base/metrics/sparse_histogram.h" | |
| 21 #include "base/strings/string_number_conversions.h" | |
| 22 #include "net/android/network_library.h" | |
| 23 #endif | |
| 24 | |
| 25 #if defined(OS_WIN) | |
| 26 #include "net/base/network_change_notifier_win.h" | |
| 27 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
| 28 #include "net/base/network_change_notifier_linux.h" | |
| 29 #elif defined(OS_MACOSX) | |
| 30 #include "net/base/network_change_notifier_mac.h" | |
| 31 #endif | |
| 32 | |
| 33 namespace net { | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 // The actual singleton notifier. The class contract forbids usage of the API | |
| 38 // in ways that would require us to place locks around access to this object. | |
| 39 // (The prohibition on global non-POD objects makes it tricky to do such a thing | |
| 40 // anyway.) | |
| 41 NetworkChangeNotifier* g_network_change_notifier = NULL; | |
| 42 | |
| 43 // Class factory singleton. | |
| 44 NetworkChangeNotifierFactory* g_network_change_notifier_factory = NULL; | |
| 45 | |
| 46 class MockNetworkChangeNotifier : public NetworkChangeNotifier { | |
| 47 public: | |
| 48 ConnectionType GetCurrentConnectionType() const override { | |
| 49 return CONNECTION_UNKNOWN; | |
| 50 } | |
| 51 }; | |
| 52 | |
| 53 } // namespace | |
| 54 | |
| 55 // The main observer class that records UMAs for network events. | |
| 56 class HistogramWatcher | |
| 57 : public NetworkChangeNotifier::ConnectionTypeObserver, | |
| 58 public NetworkChangeNotifier::IPAddressObserver, | |
| 59 public NetworkChangeNotifier::DNSObserver, | |
| 60 public NetworkChangeNotifier::NetworkChangeObserver { | |
| 61 public: | |
| 62 HistogramWatcher() | |
| 63 : last_ip_address_change_(base::TimeTicks::Now()), | |
| 64 last_connection_change_(base::TimeTicks::Now()), | |
| 65 last_dns_change_(base::TimeTicks::Now()), | |
| 66 last_network_change_(base::TimeTicks::Now()), | |
| 67 last_connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), | |
| 68 offline_packets_received_(0), | |
| 69 bytes_read_since_last_connection_change_(0), | |
| 70 peak_kbps_since_last_connection_change_(0) {} | |
| 71 | |
| 72 // Registers our three Observer implementations. This is called from the | |
| 73 // network thread so that our Observer implementations are also called | |
| 74 // from the network thread. This avoids multi-threaded race conditions | |
| 75 // because the only other interface, |NotifyDataReceived| is also | |
| 76 // only called from the network thread. | |
| 77 void Init() { | |
| 78 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 79 DCHECK(g_network_change_notifier); | |
| 80 NetworkChangeNotifier::AddConnectionTypeObserver(this); | |
| 81 NetworkChangeNotifier::AddIPAddressObserver(this); | |
| 82 NetworkChangeNotifier::AddDNSObserver(this); | |
| 83 NetworkChangeNotifier::AddNetworkChangeObserver(this); | |
| 84 } | |
| 85 | |
| 86 ~HistogramWatcher() override { | |
| 87 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 88 DCHECK(g_network_change_notifier); | |
| 89 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | |
| 90 NetworkChangeNotifier::RemoveIPAddressObserver(this); | |
| 91 NetworkChangeNotifier::RemoveDNSObserver(this); | |
| 92 NetworkChangeNotifier::RemoveNetworkChangeObserver(this); | |
| 93 } | |
| 94 | |
| 95 // NetworkChangeNotifier::IPAddressObserver implementation. | |
| 96 void OnIPAddressChanged() override { | |
| 97 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 98 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange", | |
| 99 SinceLast(&last_ip_address_change_)); | |
| 100 UMA_HISTOGRAM_MEDIUM_TIMES( | |
| 101 "NCN.ConnectionTypeChangeToIPAddressChange", | |
| 102 last_ip_address_change_ - last_connection_change_); | |
| 103 } | |
| 104 | |
| 105 // NetworkChangeNotifier::ConnectionTypeObserver implementation. | |
| 106 void OnConnectionTypeChanged( | |
| 107 NetworkChangeNotifier::ConnectionType type) override { | |
| 108 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 109 base::TimeTicks now = base::TimeTicks::Now(); | |
| 110 int32 kilobytes_read = bytes_read_since_last_connection_change_ / 1000; | |
| 111 base::TimeDelta state_duration = SinceLast(&last_connection_change_); | |
| 112 if (bytes_read_since_last_connection_change_) { | |
| 113 switch (last_connection_type_) { | |
| 114 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 115 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOnUnknown", | |
| 116 first_byte_after_connection_change_); | |
| 117 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOnUnknown", | |
| 118 fastest_RTT_since_last_connection_change_); | |
| 119 break; | |
| 120 case NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 121 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOnEthernet", | |
| 122 first_byte_after_connection_change_); | |
| 123 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOnEthernet", | |
| 124 fastest_RTT_since_last_connection_change_); | |
| 125 break; | |
| 126 case NetworkChangeNotifier::CONNECTION_WIFI: | |
| 127 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOnWifi", | |
| 128 first_byte_after_connection_change_); | |
| 129 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOnWifi", | |
| 130 fastest_RTT_since_last_connection_change_); | |
| 131 break; | |
| 132 case NetworkChangeNotifier::CONNECTION_2G: | |
| 133 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOn2G", | |
| 134 first_byte_after_connection_change_); | |
| 135 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOn2G", | |
| 136 fastest_RTT_since_last_connection_change_); | |
| 137 break; | |
| 138 case NetworkChangeNotifier::CONNECTION_3G: | |
| 139 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOn3G", | |
| 140 first_byte_after_connection_change_); | |
| 141 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOn3G", | |
| 142 fastest_RTT_since_last_connection_change_); | |
| 143 break; | |
| 144 case NetworkChangeNotifier::CONNECTION_4G: | |
| 145 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOn4G", | |
| 146 first_byte_after_connection_change_); | |
| 147 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOn4G", | |
| 148 fastest_RTT_since_last_connection_change_); | |
| 149 break; | |
| 150 case NetworkChangeNotifier::CONNECTION_NONE: | |
| 151 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOnNone", | |
| 152 first_byte_after_connection_change_); | |
| 153 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOnNone", | |
| 154 fastest_RTT_since_last_connection_change_); | |
| 155 break; | |
| 156 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 157 UMA_HISTOGRAM_TIMES("NCN.CM.FirstReadOnBluetooth", | |
| 158 first_byte_after_connection_change_); | |
| 159 UMA_HISTOGRAM_TIMES("NCN.CM.FastestRTTOnBluetooth", | |
| 160 fastest_RTT_since_last_connection_change_); | |
| 161 } | |
| 162 } | |
| 163 if (peak_kbps_since_last_connection_change_) { | |
| 164 switch (last_connection_type_) { | |
| 165 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 166 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnUnknown", | |
| 167 peak_kbps_since_last_connection_change_); | |
| 168 break; | |
| 169 case NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 170 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnEthernet", | |
| 171 peak_kbps_since_last_connection_change_); | |
| 172 break; | |
| 173 case NetworkChangeNotifier::CONNECTION_WIFI: | |
| 174 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnWifi", | |
| 175 peak_kbps_since_last_connection_change_); | |
| 176 break; | |
| 177 case NetworkChangeNotifier::CONNECTION_2G: | |
| 178 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn2G", | |
| 179 peak_kbps_since_last_connection_change_); | |
| 180 break; | |
| 181 case NetworkChangeNotifier::CONNECTION_3G: | |
| 182 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn3G", | |
| 183 peak_kbps_since_last_connection_change_); | |
| 184 break; | |
| 185 case NetworkChangeNotifier::CONNECTION_4G: | |
| 186 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn4G", | |
| 187 peak_kbps_since_last_connection_change_); | |
| 188 break; | |
| 189 case NetworkChangeNotifier::CONNECTION_NONE: | |
| 190 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnNone", | |
| 191 peak_kbps_since_last_connection_change_); | |
| 192 break; | |
| 193 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 194 UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnBluetooth", | |
| 195 peak_kbps_since_last_connection_change_); | |
| 196 break; | |
| 197 } | |
| 198 } | |
| 199 switch (last_connection_type_) { | |
| 200 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 201 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnUnknown", state_duration); | |
| 202 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnUnknown", kilobytes_read); | |
| 203 break; | |
| 204 case NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 205 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnEthernet", state_duration); | |
| 206 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnEthernet", kilobytes_read); | |
| 207 break; | |
| 208 case NetworkChangeNotifier::CONNECTION_WIFI: | |
| 209 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnWifi", state_duration); | |
| 210 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnWifi", kilobytes_read); | |
| 211 break; | |
| 212 case NetworkChangeNotifier::CONNECTION_2G: | |
| 213 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn2G", state_duration); | |
| 214 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn2G", kilobytes_read); | |
| 215 break; | |
| 216 case NetworkChangeNotifier::CONNECTION_3G: | |
| 217 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn3G", state_duration); | |
| 218 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn3G", kilobytes_read); | |
| 219 break; | |
| 220 case NetworkChangeNotifier::CONNECTION_4G: | |
| 221 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn4G", state_duration); | |
| 222 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn4G", kilobytes_read); | |
| 223 break; | |
| 224 case NetworkChangeNotifier::CONNECTION_NONE: | |
| 225 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnNone", state_duration); | |
| 226 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnNone", kilobytes_read); | |
| 227 break; | |
| 228 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 229 UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnBluetooth", state_duration); | |
| 230 UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnBluetooth", kilobytes_read); | |
| 231 break; | |
| 232 } | |
| 233 | |
| 234 if (type != NetworkChangeNotifier::CONNECTION_NONE) { | |
| 235 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OnlineChange", state_duration); | |
| 236 | |
| 237 if (offline_packets_received_) { | |
| 238 if ((now - last_offline_packet_received_) < | |
| 239 base::TimeDelta::FromSeconds(5)) { | |
| 240 // We can compare this sum with the sum of NCN.OfflineDataRecv. | |
| 241 UMA_HISTOGRAM_COUNTS_10000( | |
| 242 "NCN.OfflineDataRecvAny5sBeforeOnline", | |
| 243 offline_packets_received_); | |
| 244 } | |
| 245 | |
| 246 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecvUntilOnline", | |
| 247 now - last_offline_packet_received_); | |
| 248 } | |
| 249 } else { | |
| 250 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange", state_duration); | |
| 251 } | |
| 252 | |
| 253 NetworkChangeNotifier::LogOperatorCodeHistogram(type); | |
| 254 | |
| 255 UMA_HISTOGRAM_MEDIUM_TIMES( | |
| 256 "NCN.IPAddressChangeToConnectionTypeChange", | |
| 257 now - last_ip_address_change_); | |
| 258 | |
| 259 offline_packets_received_ = 0; | |
| 260 bytes_read_since_last_connection_change_ = 0; | |
| 261 peak_kbps_since_last_connection_change_ = 0; | |
| 262 last_connection_type_ = type; | |
| 263 polling_interval_ = base::TimeDelta::FromSeconds(1); | |
| 264 } | |
| 265 | |
| 266 // NetworkChangeNotifier::DNSObserver implementation. | |
| 267 void OnDNSChanged() override { | |
| 268 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 269 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.DNSConfigChange", | |
| 270 SinceLast(&last_dns_change_)); | |
| 271 } | |
| 272 | |
| 273 // NetworkChangeNotifier::NetworkChangeObserver implementation. | |
| 274 void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) override { | |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 276 if (type != NetworkChangeNotifier::CONNECTION_NONE) { | |
| 277 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOnlineChange", | |
| 278 SinceLast(&last_network_change_)); | |
| 279 } else { | |
| 280 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOfflineChange", | |
| 281 SinceLast(&last_network_change_)); | |
| 282 } | |
| 283 } | |
| 284 | |
| 285 // Record histogram data whenever we receive a packet. Should only be called | |
| 286 // from the network thread. | |
| 287 void NotifyDataReceived(const URLRequest& request, int bytes_read) { | |
| 288 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 289 if (IsLocalhost(request.url().host()) || | |
| 290 !request.url().SchemeIsHTTPOrHTTPS()) { | |
| 291 return; | |
| 292 } | |
| 293 | |
| 294 base::TimeTicks now = base::TimeTicks::Now(); | |
| 295 base::TimeDelta request_duration = now - request.creation_time(); | |
| 296 if (bytes_read_since_last_connection_change_ == 0) { | |
| 297 first_byte_after_connection_change_ = now - last_connection_change_; | |
| 298 fastest_RTT_since_last_connection_change_ = request_duration; | |
| 299 } | |
| 300 bytes_read_since_last_connection_change_ += bytes_read; | |
| 301 if (request_duration < fastest_RTT_since_last_connection_change_) | |
| 302 fastest_RTT_since_last_connection_change_ = request_duration; | |
| 303 // Ignore tiny transfers which will not produce accurate rates. | |
| 304 // Ignore zero duration transfers which might cause divide by zero. | |
| 305 if (bytes_read > 10000 && | |
| 306 request_duration > base::TimeDelta::FromMilliseconds(1) && | |
| 307 request.creation_time() > last_connection_change_) { | |
| 308 int32 kbps = static_cast<int32>( | |
| 309 bytes_read * 8 / request_duration.InMilliseconds()); | |
| 310 if (kbps > peak_kbps_since_last_connection_change_) | |
| 311 peak_kbps_since_last_connection_change_ = kbps; | |
| 312 } | |
| 313 | |
| 314 if (last_connection_type_ != NetworkChangeNotifier::CONNECTION_NONE) | |
| 315 return; | |
| 316 | |
| 317 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineDataRecv", | |
| 318 now - last_connection_change_); | |
| 319 offline_packets_received_++; | |
| 320 last_offline_packet_received_ = now; | |
| 321 | |
| 322 if ((now - last_polled_connection_) > polling_interval_) { | |
| 323 polling_interval_ *= 2; | |
| 324 last_polled_connection_ = now; | |
| 325 last_polled_connection_type_ = | |
| 326 NetworkChangeNotifier::GetConnectionType(); | |
| 327 } | |
| 328 if (last_polled_connection_type_ == | |
| 329 NetworkChangeNotifier::CONNECTION_NONE) { | |
| 330 UMA_HISTOGRAM_MEDIUM_TIMES("NCN.PollingOfflineDataRecv", | |
| 331 now - last_connection_change_); | |
| 332 } | |
| 333 } | |
| 334 | |
| 335 private: | |
| 336 static base::TimeDelta SinceLast(base::TimeTicks *last_time) { | |
| 337 base::TimeTicks current_time = base::TimeTicks::Now(); | |
| 338 base::TimeDelta delta = current_time - *last_time; | |
| 339 *last_time = current_time; | |
| 340 return delta; | |
| 341 } | |
| 342 | |
| 343 base::TimeTicks last_ip_address_change_; | |
| 344 base::TimeTicks last_connection_change_; | |
| 345 base::TimeTicks last_dns_change_; | |
| 346 base::TimeTicks last_network_change_; | |
| 347 base::TimeTicks last_offline_packet_received_; | |
| 348 base::TimeTicks last_polled_connection_; | |
| 349 // |polling_interval_| is initialized by |OnConnectionTypeChanged| on our | |
| 350 // first transition to offline and on subsequent transitions. Once offline, | |
| 351 // |polling_interval_| doubles as offline data is received and we poll | |
| 352 // with |NetworkChangeNotifier::GetConnectionType| to verify the connection | |
| 353 // state. | |
| 354 base::TimeDelta polling_interval_; | |
| 355 // |last_connection_type_| is the last value passed to | |
| 356 // |OnConnectionTypeChanged|. | |
| 357 NetworkChangeNotifier::ConnectionType last_connection_type_; | |
| 358 // |last_polled_connection_type_| is last result from calling | |
| 359 // |NetworkChangeNotifier::GetConnectionType| in |NotifyDataReceived|. | |
| 360 NetworkChangeNotifier::ConnectionType last_polled_connection_type_; | |
| 361 // Count of how many times NotifyDataReceived() has been called while the | |
| 362 // NetworkChangeNotifier thought network connection was offline. | |
| 363 int32 offline_packets_received_; | |
| 364 // Number of bytes of network data received since last connectivity change. | |
| 365 int32 bytes_read_since_last_connection_change_; | |
| 366 // Fastest round-trip-time (RTT) since last connectivity change. RTT measured | |
| 367 // from URLRequest creation until first byte received. | |
| 368 base::TimeDelta fastest_RTT_since_last_connection_change_; | |
| 369 // Time between connectivity change and first network data byte received. | |
| 370 base::TimeDelta first_byte_after_connection_change_; | |
| 371 // Rough measurement of peak KB/s witnessed since last connectivity change. | |
| 372 // The accuracy is decreased by ignoring these factors: | |
| 373 // 1) Multiple URLRequests can occur concurrently. | |
| 374 // 2) NotifyDataReceived() may be called repeatedly for one URLRequest. | |
| 375 // 3) The transfer time includes at least one RTT while no bytes are read. | |
| 376 // Erring on the conservative side is hopefully offset by taking the maximum. | |
| 377 int32 peak_kbps_since_last_connection_change_; | |
| 378 | |
| 379 base::ThreadChecker thread_checker_; | |
| 380 | |
| 381 DISALLOW_COPY_AND_ASSIGN(HistogramWatcher); | |
| 382 }; | |
| 383 | |
| 384 // NetworkState is thread safe. | |
| 385 class NetworkChangeNotifier::NetworkState { | |
| 386 public: | |
| 387 NetworkState() {} | |
| 388 ~NetworkState() {} | |
| 389 | |
| 390 void GetDnsConfig(DnsConfig* config) const { | |
| 391 base::AutoLock lock(lock_); | |
| 392 *config = dns_config_; | |
| 393 } | |
| 394 | |
| 395 void SetDnsConfig(const DnsConfig& dns_config) { | |
| 396 base::AutoLock lock(lock_); | |
| 397 dns_config_ = dns_config; | |
| 398 } | |
| 399 | |
| 400 private: | |
| 401 mutable base::Lock lock_; | |
| 402 DnsConfig dns_config_; | |
| 403 }; | |
| 404 | |
| 405 NetworkChangeNotifier::NetworkChangeCalculatorParams:: | |
| 406 NetworkChangeCalculatorParams() { | |
| 407 } | |
| 408 | |
| 409 // Calculates NetworkChange signal from IPAddress and ConnectionType signals. | |
| 410 class NetworkChangeNotifier::NetworkChangeCalculator | |
| 411 : public ConnectionTypeObserver, | |
| 412 public IPAddressObserver { | |
| 413 public: | |
| 414 NetworkChangeCalculator(const NetworkChangeCalculatorParams& params) | |
| 415 : params_(params), | |
| 416 have_announced_(false), | |
| 417 last_announced_connection_type_(CONNECTION_NONE), | |
| 418 pending_connection_type_(CONNECTION_NONE) {} | |
| 419 | |
| 420 void Init() { | |
| 421 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 422 DCHECK(g_network_change_notifier); | |
| 423 AddConnectionTypeObserver(this); | |
| 424 AddIPAddressObserver(this); | |
| 425 } | |
| 426 | |
| 427 ~NetworkChangeCalculator() override { | |
| 428 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 429 DCHECK(g_network_change_notifier); | |
| 430 RemoveConnectionTypeObserver(this); | |
| 431 RemoveIPAddressObserver(this); | |
| 432 } | |
| 433 | |
| 434 // NetworkChangeNotifier::IPAddressObserver implementation. | |
| 435 void OnIPAddressChanged() override { | |
| 436 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 437 base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE | |
| 438 ? params_.ip_address_offline_delay_ : params_.ip_address_online_delay_; | |
| 439 // Cancels any previous timer. | |
| 440 timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify); | |
| 441 } | |
| 442 | |
| 443 // NetworkChangeNotifier::ConnectionTypeObserver implementation. | |
| 444 void OnConnectionTypeChanged(ConnectionType type) override { | |
| 445 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 446 pending_connection_type_ = type; | |
| 447 base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE | |
| 448 ? params_.connection_type_offline_delay_ | |
| 449 : params_.connection_type_online_delay_; | |
| 450 // Cancels any previous timer. | |
| 451 timer_.Start(FROM_HERE, delay, this, &NetworkChangeCalculator::Notify); | |
| 452 } | |
| 453 | |
| 454 private: | |
| 455 void Notify() { | |
| 456 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 457 // Don't bother signaling about dead connections. | |
| 458 if (have_announced_ && | |
| 459 (last_announced_connection_type_ == CONNECTION_NONE) && | |
| 460 (pending_connection_type_ == CONNECTION_NONE)) { | |
| 461 return; | |
| 462 } | |
| 463 have_announced_ = true; | |
| 464 last_announced_connection_type_ = pending_connection_type_; | |
| 465 // Immediately before sending out an online signal, send out an offline | |
| 466 // signal to perform any destructive actions before constructive actions. | |
| 467 if (pending_connection_type_ != CONNECTION_NONE) | |
| 468 NetworkChangeNotifier::NotifyObserversOfNetworkChange(CONNECTION_NONE); | |
| 469 NetworkChangeNotifier::NotifyObserversOfNetworkChange( | |
| 470 pending_connection_type_); | |
| 471 } | |
| 472 | |
| 473 const NetworkChangeCalculatorParams params_; | |
| 474 | |
| 475 // Indicates if NotifyObserversOfNetworkChange has been called yet. | |
| 476 bool have_announced_; | |
| 477 // Last value passed to NotifyObserversOfNetworkChange. | |
| 478 ConnectionType last_announced_connection_type_; | |
| 479 // Value to pass to NotifyObserversOfNetworkChange when Notify is called. | |
| 480 ConnectionType pending_connection_type_; | |
| 481 // Used to delay notifications so duplicates can be combined. | |
| 482 base::OneShotTimer<NetworkChangeCalculator> timer_; | |
| 483 | |
| 484 base::ThreadChecker thread_checker_; | |
| 485 | |
| 486 DISALLOW_COPY_AND_ASSIGN(NetworkChangeCalculator); | |
| 487 }; | |
| 488 | |
| 489 NetworkChangeNotifier::~NetworkChangeNotifier() { | |
| 490 network_change_calculator_.reset(); | |
| 491 DCHECK_EQ(this, g_network_change_notifier); | |
| 492 g_network_change_notifier = NULL; | |
| 493 } | |
| 494 | |
| 495 // static | |
| 496 void NetworkChangeNotifier::SetFactory( | |
| 497 NetworkChangeNotifierFactory* factory) { | |
| 498 CHECK(!g_network_change_notifier_factory); | |
| 499 g_network_change_notifier_factory = factory; | |
| 500 } | |
| 501 | |
| 502 // static | |
| 503 NetworkChangeNotifier* NetworkChangeNotifier::Create() { | |
| 504 if (g_network_change_notifier_factory) | |
| 505 return g_network_change_notifier_factory->CreateInstance(); | |
| 506 | |
| 507 #if defined(OS_WIN) | |
| 508 NetworkChangeNotifierWin* network_change_notifier = | |
| 509 new NetworkChangeNotifierWin(); | |
| 510 network_change_notifier->WatchForAddressChange(); | |
| 511 return network_change_notifier; | |
| 512 #elif defined(OS_CHROMEOS) || defined(OS_ANDROID) | |
| 513 // ChromeOS and Android builds MUST use their own class factory. | |
| 514 #if !defined(OS_CHROMEOS) | |
| 515 // TODO(oshima): ash_shell do not have access to chromeos'es | |
| 516 // notifier yet. Re-enable this when chromeos'es notifier moved to | |
| 517 // chromeos root directory. crbug.com/119298. | |
| 518 CHECK(false); | |
| 519 #endif | |
| 520 return NULL; | |
| 521 #elif defined(OS_LINUX) | |
| 522 return NetworkChangeNotifierLinux::Create(); | |
| 523 #elif defined(OS_MACOSX) | |
| 524 return new NetworkChangeNotifierMac(); | |
| 525 #else | |
| 526 NOTIMPLEMENTED(); | |
| 527 return NULL; | |
| 528 #endif | |
| 529 } | |
| 530 | |
| 531 // static | |
| 532 NetworkChangeNotifier::ConnectionType | |
| 533 NetworkChangeNotifier::GetConnectionType() { | |
| 534 return g_network_change_notifier ? | |
| 535 g_network_change_notifier->GetCurrentConnectionType() : | |
| 536 CONNECTION_UNKNOWN; | |
| 537 } | |
| 538 | |
| 539 // static | |
| 540 double NetworkChangeNotifier::GetMaxBandwidth() { | |
| 541 return g_network_change_notifier ? | |
| 542 g_network_change_notifier->GetCurrentMaxBandwidth() : | |
| 543 std::numeric_limits<double>::infinity(); | |
| 544 } | |
| 545 | |
| 546 // static | |
| 547 void NetworkChangeNotifier::GetDnsConfig(DnsConfig* config) { | |
| 548 if (!g_network_change_notifier) { | |
| 549 *config = DnsConfig(); | |
| 550 } else { | |
| 551 g_network_change_notifier->network_state_->GetDnsConfig(config); | |
| 552 } | |
| 553 } | |
| 554 | |
| 555 // static | |
| 556 const char* NetworkChangeNotifier::ConnectionTypeToString( | |
| 557 ConnectionType type) { | |
| 558 static const char* const kConnectionTypeNames[] = { | |
| 559 "CONNECTION_UNKNOWN", | |
| 560 "CONNECTION_ETHERNET", | |
| 561 "CONNECTION_WIFI", | |
| 562 "CONNECTION_2G", | |
| 563 "CONNECTION_3G", | |
| 564 "CONNECTION_4G", | |
| 565 "CONNECTION_NONE", | |
| 566 "CONNECTION_BLUETOOTH" | |
| 567 }; | |
| 568 static_assert(arraysize(kConnectionTypeNames) == | |
| 569 NetworkChangeNotifier::CONNECTION_LAST + 1, | |
| 570 "ConnectionType name count should match"); | |
| 571 if (type < CONNECTION_UNKNOWN || type > CONNECTION_LAST) { | |
| 572 NOTREACHED(); | |
| 573 return "CONNECTION_INVALID"; | |
| 574 } | |
| 575 return kConnectionTypeNames[type]; | |
| 576 } | |
| 577 | |
| 578 // static | |
| 579 void NetworkChangeNotifier::NotifyDataReceived(const URLRequest& request, | |
| 580 int bytes_read) { | |
| 581 if (!g_network_change_notifier || | |
| 582 !g_network_change_notifier->histogram_watcher_) { | |
| 583 return; | |
| 584 } | |
| 585 g_network_change_notifier->histogram_watcher_->NotifyDataReceived(request, | |
| 586 bytes_read); | |
| 587 } | |
| 588 | |
| 589 // static | |
| 590 void NetworkChangeNotifier::InitHistogramWatcher() { | |
| 591 if (!g_network_change_notifier) | |
| 592 return; | |
| 593 g_network_change_notifier->histogram_watcher_.reset(new HistogramWatcher()); | |
| 594 g_network_change_notifier->histogram_watcher_->Init(); | |
| 595 } | |
| 596 | |
| 597 // static | |
| 598 void NetworkChangeNotifier::ShutdownHistogramWatcher() { | |
| 599 if (!g_network_change_notifier) | |
| 600 return; | |
| 601 g_network_change_notifier->histogram_watcher_.reset(); | |
| 602 } | |
| 603 | |
| 604 // static | |
| 605 void NetworkChangeNotifier::LogOperatorCodeHistogram(ConnectionType type) { | |
| 606 #if defined(OS_ANDROID) | |
| 607 // On a connection type change to 2/3/4G, log the network operator MCC/MNC. | |
| 608 // Log zero in other cases. | |
| 609 unsigned mcc_mnc = 0; | |
| 610 if (type == NetworkChangeNotifier::CONNECTION_2G || | |
| 611 type == NetworkChangeNotifier::CONNECTION_3G || | |
| 612 type == NetworkChangeNotifier::CONNECTION_4G) { | |
| 613 // Log zero if not perfectly converted. | |
| 614 if (!base::StringToUint( | |
| 615 net::android::GetTelephonyNetworkOperator(), &mcc_mnc)) { | |
| 616 mcc_mnc = 0; | |
| 617 } | |
| 618 } | |
| 619 UMA_HISTOGRAM_SPARSE_SLOWLY("NCN.NetworkOperatorMCCMNC", mcc_mnc); | |
| 620 #endif | |
| 621 } | |
| 622 | |
| 623 #if defined(OS_LINUX) | |
| 624 // static | |
| 625 const internal::AddressTrackerLinux* | |
| 626 NetworkChangeNotifier::GetAddressTracker() { | |
| 627 return g_network_change_notifier ? | |
| 628 g_network_change_notifier->GetAddressTrackerInternal() : NULL; | |
| 629 } | |
| 630 #endif | |
| 631 | |
| 632 // static | |
| 633 bool NetworkChangeNotifier::IsOffline() { | |
| 634 return GetConnectionType() == CONNECTION_NONE; | |
| 635 } | |
| 636 | |
| 637 // static | |
| 638 bool NetworkChangeNotifier::IsConnectionCellular(ConnectionType type) { | |
| 639 bool is_cellular = false; | |
| 640 switch (type) { | |
| 641 case CONNECTION_2G: | |
| 642 case CONNECTION_3G: | |
| 643 case CONNECTION_4G: | |
| 644 is_cellular = true; | |
| 645 break; | |
| 646 case CONNECTION_UNKNOWN: | |
| 647 case CONNECTION_ETHERNET: | |
| 648 case CONNECTION_WIFI: | |
| 649 case CONNECTION_NONE: | |
| 650 case CONNECTION_BLUETOOTH: | |
| 651 is_cellular = false; | |
| 652 break; | |
| 653 } | |
| 654 return is_cellular; | |
| 655 } | |
| 656 | |
| 657 // static | |
| 658 NetworkChangeNotifier::ConnectionType | |
| 659 NetworkChangeNotifier::ConnectionTypeFromInterfaceList( | |
| 660 const NetworkInterfaceList& interfaces) { | |
| 661 bool first = true; | |
| 662 ConnectionType result = CONNECTION_NONE; | |
| 663 for (size_t i = 0; i < interfaces.size(); ++i) { | |
| 664 #if defined(OS_WIN) | |
| 665 if (interfaces[i].friendly_name == "Teredo Tunneling Pseudo-Interface") | |
| 666 continue; | |
| 667 #endif | |
| 668 if (first) { | |
| 669 first = false; | |
| 670 result = interfaces[i].type; | |
| 671 } else if (result != interfaces[i].type) { | |
| 672 return CONNECTION_UNKNOWN; | |
| 673 } | |
| 674 } | |
| 675 return result; | |
| 676 } | |
| 677 | |
| 678 // static | |
| 679 NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { | |
| 680 return new MockNetworkChangeNotifier(); | |
| 681 } | |
| 682 | |
| 683 void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) { | |
| 684 if (g_network_change_notifier) | |
| 685 g_network_change_notifier->ip_address_observer_list_->AddObserver(observer); | |
| 686 } | |
| 687 | |
| 688 void NetworkChangeNotifier::AddConnectionTypeObserver( | |
| 689 ConnectionTypeObserver* observer) { | |
| 690 if (g_network_change_notifier) { | |
| 691 g_network_change_notifier->connection_type_observer_list_->AddObserver( | |
| 692 observer); | |
| 693 } | |
| 694 } | |
| 695 | |
| 696 void NetworkChangeNotifier::AddDNSObserver(DNSObserver* observer) { | |
| 697 if (g_network_change_notifier) { | |
| 698 g_network_change_notifier->resolver_state_observer_list_->AddObserver( | |
| 699 observer); | |
| 700 } | |
| 701 } | |
| 702 | |
| 703 void NetworkChangeNotifier::AddNetworkChangeObserver( | |
| 704 NetworkChangeObserver* observer) { | |
| 705 if (g_network_change_notifier) { | |
| 706 g_network_change_notifier->network_change_observer_list_->AddObserver( | |
| 707 observer); | |
| 708 } | |
| 709 } | |
| 710 | |
| 711 void NetworkChangeNotifier::AddMaxBandwidthObserver( | |
| 712 MaxBandwidthObserver* observer) { | |
| 713 if (g_network_change_notifier) { | |
| 714 g_network_change_notifier->max_bandwidth_observer_list_->AddObserver( | |
| 715 observer); | |
| 716 } | |
| 717 } | |
| 718 | |
| 719 void NetworkChangeNotifier::RemoveIPAddressObserver( | |
| 720 IPAddressObserver* observer) { | |
| 721 if (g_network_change_notifier) { | |
| 722 g_network_change_notifier->ip_address_observer_list_->RemoveObserver( | |
| 723 observer); | |
| 724 } | |
| 725 } | |
| 726 | |
| 727 void NetworkChangeNotifier::RemoveConnectionTypeObserver( | |
| 728 ConnectionTypeObserver* observer) { | |
| 729 if (g_network_change_notifier) { | |
| 730 g_network_change_notifier->connection_type_observer_list_->RemoveObserver( | |
| 731 observer); | |
| 732 } | |
| 733 } | |
| 734 | |
| 735 void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver* observer) { | |
| 736 if (g_network_change_notifier) { | |
| 737 g_network_change_notifier->resolver_state_observer_list_->RemoveObserver( | |
| 738 observer); | |
| 739 } | |
| 740 } | |
| 741 | |
| 742 void NetworkChangeNotifier::RemoveNetworkChangeObserver( | |
| 743 NetworkChangeObserver* observer) { | |
| 744 if (g_network_change_notifier) { | |
| 745 g_network_change_notifier->network_change_observer_list_->RemoveObserver( | |
| 746 observer); | |
| 747 } | |
| 748 } | |
| 749 | |
| 750 void NetworkChangeNotifier::RemoveMaxBandwidthObserver( | |
| 751 MaxBandwidthObserver* observer) { | |
| 752 if (g_network_change_notifier) { | |
| 753 g_network_change_notifier->max_bandwidth_observer_list_->RemoveObserver( | |
| 754 observer); | |
| 755 } | |
| 756 } | |
| 757 | |
| 758 // static | |
| 759 void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests() { | |
| 760 if (g_network_change_notifier) | |
| 761 g_network_change_notifier->NotifyObserversOfIPAddressChangeImpl(); | |
| 762 } | |
| 763 | |
| 764 // static | |
| 765 void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests( | |
| 766 ConnectionType type) { | |
| 767 if (g_network_change_notifier) | |
| 768 g_network_change_notifier->NotifyObserversOfConnectionTypeChangeImpl(type); | |
| 769 } | |
| 770 | |
| 771 // static | |
| 772 void NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( | |
| 773 ConnectionType type) { | |
| 774 if (g_network_change_notifier) | |
| 775 g_network_change_notifier->NotifyObserversOfNetworkChangeImpl(type); | |
| 776 } | |
| 777 | |
| 778 // static | |
| 779 void NetworkChangeNotifier::SetTestNotificationsOnly(bool test_only) { | |
| 780 if (g_network_change_notifier) | |
| 781 g_network_change_notifier->test_notifications_only_ = test_only; | |
| 782 } | |
| 783 | |
| 784 NetworkChangeNotifier::NetworkChangeNotifier( | |
| 785 const NetworkChangeCalculatorParams& params | |
| 786 /*= NetworkChangeCalculatorParams()*/) | |
| 787 : ip_address_observer_list_(new ObserverListThreadSafe<IPAddressObserver>( | |
| 788 ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)), | |
| 789 connection_type_observer_list_( | |
| 790 new ObserverListThreadSafe<ConnectionTypeObserver>( | |
| 791 ObserverListBase<ConnectionTypeObserver>::NOTIFY_EXISTING_ONLY)), | |
| 792 resolver_state_observer_list_(new ObserverListThreadSafe<DNSObserver>( | |
| 793 ObserverListBase<DNSObserver>::NOTIFY_EXISTING_ONLY)), | |
| 794 network_change_observer_list_( | |
| 795 new ObserverListThreadSafe<NetworkChangeObserver>( | |
| 796 ObserverListBase<NetworkChangeObserver>::NOTIFY_EXISTING_ONLY)), | |
| 797 max_bandwidth_observer_list_( | |
| 798 new ObserverListThreadSafe<MaxBandwidthObserver>( | |
| 799 ObserverListBase<MaxBandwidthObserver>::NOTIFY_EXISTING_ONLY)), | |
| 800 network_state_(new NetworkState()), | |
| 801 network_change_calculator_(new NetworkChangeCalculator(params)), | |
| 802 test_notifications_only_(false) { | |
| 803 DCHECK(!g_network_change_notifier); | |
| 804 g_network_change_notifier = this; | |
| 805 network_change_calculator_->Init(); | |
| 806 } | |
| 807 | |
| 808 #if defined(OS_LINUX) | |
| 809 const internal::AddressTrackerLinux* | |
| 810 NetworkChangeNotifier::GetAddressTrackerInternal() const { | |
| 811 return NULL; | |
| 812 } | |
| 813 #endif | |
| 814 | |
| 815 double NetworkChangeNotifier::GetCurrentMaxBandwidth() const { | |
| 816 // This default implementation conforms to the NetInfo V3 specification but | |
| 817 // should be overridden to provide specific bandwidth data based on the | |
| 818 // platform. | |
| 819 if (GetCurrentConnectionType() == CONNECTION_NONE) | |
| 820 return 0.0; | |
| 821 return std::numeric_limits<double>::infinity(); | |
| 822 } | |
| 823 | |
| 824 // static | |
| 825 double NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype( | |
| 826 ConnectionSubtype subtype) { | |
| 827 switch (subtype) { | |
| 828 case SUBTYPE_GSM: | |
| 829 return 0.01; | |
| 830 case SUBTYPE_IDEN: | |
| 831 return 0.064; | |
| 832 case SUBTYPE_CDMA: | |
| 833 return 0.115; | |
| 834 case SUBTYPE_1XRTT: | |
| 835 return 0.153; | |
| 836 case SUBTYPE_GPRS: | |
| 837 return 0.237; | |
| 838 case SUBTYPE_EDGE: | |
| 839 return 0.384; | |
| 840 case SUBTYPE_UMTS: | |
| 841 return 2.0; | |
| 842 case SUBTYPE_EVDO_REV_0: | |
| 843 return 2.46; | |
| 844 case SUBTYPE_EVDO_REV_A: | |
| 845 return 3.1; | |
| 846 case SUBTYPE_HSPA: | |
| 847 return 3.6; | |
| 848 case SUBTYPE_EVDO_REV_B: | |
| 849 return 14.7; | |
| 850 case SUBTYPE_HSDPA: | |
| 851 return 14.3; | |
| 852 case SUBTYPE_HSUPA: | |
| 853 return 14.4; | |
| 854 case SUBTYPE_EHRPD: | |
| 855 return 21.0; | |
| 856 case SUBTYPE_HSPAP: | |
| 857 return 42.0; | |
| 858 case SUBTYPE_LTE: | |
| 859 return 100.0; | |
| 860 case SUBTYPE_LTE_ADVANCED: | |
| 861 return 100.0; | |
| 862 case SUBTYPE_BLUETOOTH_1_2: | |
| 863 return 1.0; | |
| 864 case SUBTYPE_BLUETOOTH_2_1: | |
| 865 return 3.0; | |
| 866 case SUBTYPE_BLUETOOTH_3_0: | |
| 867 return 24.0; | |
| 868 case SUBTYPE_BLUETOOTH_4_0: | |
| 869 return 1.0; | |
| 870 case SUBTYPE_ETHERNET: | |
| 871 return 10.0; | |
| 872 case SUBTYPE_FAST_ETHERNET: | |
| 873 return 100.0; | |
| 874 case SUBTYPE_GIGABIT_ETHERNET: | |
| 875 return 1000.0; | |
| 876 case SUBTYPE_10_GIGABIT_ETHERNET: | |
| 877 return 10000.0; | |
| 878 case SUBTYPE_WIFI_B: | |
| 879 return 11.0; | |
| 880 case SUBTYPE_WIFI_G: | |
| 881 return 54.0; | |
| 882 case SUBTYPE_WIFI_N: | |
| 883 return 600.0; | |
| 884 case SUBTYPE_WIFI_AC: | |
| 885 return 1300.0; | |
| 886 case SUBTYPE_WIFI_AD: | |
| 887 return 7000.0; | |
| 888 case SUBTYPE_UNKNOWN: | |
| 889 return std::numeric_limits<double>::infinity(); | |
| 890 case SUBTYPE_NONE: | |
| 891 return 0.0; | |
| 892 case SUBTYPE_OTHER: | |
| 893 return std::numeric_limits<double>::infinity(); | |
| 894 } | |
| 895 NOTREACHED(); | |
| 896 return std::numeric_limits<double>::infinity(); | |
| 897 } | |
| 898 | |
| 899 // static | |
| 900 void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() { | |
| 901 if (g_network_change_notifier && | |
| 902 !g_network_change_notifier->test_notifications_only_) { | |
| 903 g_network_change_notifier->NotifyObserversOfIPAddressChangeImpl(); | |
| 904 } | |
| 905 } | |
| 906 | |
| 907 // static | |
| 908 void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() { | |
| 909 if (g_network_change_notifier && | |
| 910 !g_network_change_notifier->test_notifications_only_) { | |
| 911 g_network_change_notifier->NotifyObserversOfConnectionTypeChangeImpl( | |
| 912 GetConnectionType()); | |
| 913 } | |
| 914 } | |
| 915 | |
| 916 // static | |
| 917 void NetworkChangeNotifier::NotifyObserversOfNetworkChange( | |
| 918 ConnectionType type) { | |
| 919 if (g_network_change_notifier && | |
| 920 !g_network_change_notifier->test_notifications_only_) { | |
| 921 g_network_change_notifier->NotifyObserversOfNetworkChangeImpl(type); | |
| 922 } | |
| 923 } | |
| 924 | |
| 925 // static | |
| 926 void NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChange( | |
| 927 double max_bandwidth_mbps) { | |
| 928 if (g_network_change_notifier && | |
| 929 !g_network_change_notifier->test_notifications_only_) { | |
| 930 g_network_change_notifier->NotifyObserversOfMaxBandwidthChangeImpl( | |
| 931 max_bandwidth_mbps); | |
| 932 } | |
| 933 } | |
| 934 | |
| 935 // static | |
| 936 void NetworkChangeNotifier::NotifyObserversOfDNSChange() { | |
| 937 if (g_network_change_notifier && | |
| 938 !g_network_change_notifier->test_notifications_only_) { | |
| 939 g_network_change_notifier->NotifyObserversOfDNSChangeImpl(); | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 // static | |
| 944 void NetworkChangeNotifier::SetDnsConfig(const DnsConfig& config) { | |
| 945 if (!g_network_change_notifier) | |
| 946 return; | |
| 947 g_network_change_notifier->network_state_->SetDnsConfig(config); | |
| 948 NotifyObserversOfDNSChange(); | |
| 949 } | |
| 950 | |
| 951 void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeImpl() { | |
| 952 ip_address_observer_list_->Notify(FROM_HERE, | |
| 953 &IPAddressObserver::OnIPAddressChanged); | |
| 954 } | |
| 955 | |
| 956 void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeImpl( | |
| 957 ConnectionType type) { | |
| 958 connection_type_observer_list_->Notify( | |
| 959 FROM_HERE, &ConnectionTypeObserver::OnConnectionTypeChanged, type); | |
| 960 } | |
| 961 | |
| 962 void NetworkChangeNotifier::NotifyObserversOfNetworkChangeImpl( | |
| 963 ConnectionType type) { | |
| 964 network_change_observer_list_->Notify( | |
| 965 FROM_HERE, &NetworkChangeObserver::OnNetworkChanged, type); | |
| 966 } | |
| 967 | |
| 968 void NetworkChangeNotifier::NotifyObserversOfDNSChangeImpl() { | |
| 969 resolver_state_observer_list_->Notify(FROM_HERE, &DNSObserver::OnDNSChanged); | |
| 970 } | |
| 971 | |
| 972 void NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChangeImpl( | |
| 973 double max_bandwidth_mbps) { | |
| 974 max_bandwidth_observer_list_->Notify( | |
| 975 FROM_HERE, &MaxBandwidthObserver::OnMaxBandwidthChanged, | |
| 976 max_bandwidth_mbps); | |
| 977 } | |
| 978 | |
| 979 NetworkChangeNotifier::DisableForTest::DisableForTest() | |
| 980 : network_change_notifier_(g_network_change_notifier) { | |
| 981 DCHECK(g_network_change_notifier); | |
| 982 g_network_change_notifier = NULL; | |
| 983 } | |
| 984 | |
| 985 NetworkChangeNotifier::DisableForTest::~DisableForTest() { | |
| 986 DCHECK(!g_network_change_notifier); | |
| 987 g_network_change_notifier = network_change_notifier_; | |
| 988 } | |
| 989 | |
| 990 } // namespace net | |
| OLD | NEW |