Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/network_quality_estimator.h" | 5 #include "net/base/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "build/build_config.h" | |
| 12 #include "net/base/load_timing_info.h" | 14 #include "net/base/load_timing_info.h" |
| 13 #include "net/base/net_util.h" | 15 #include "net/base/net_util.h" |
| 14 #include "net/base/network_quality.h" | 16 #include "net/base/network_interfaces.h" |
| 15 #include "net/url_request/url_request.h" | 17 #include "net/url_request/url_request.h" |
| 16 #include "url/gurl.h" | 18 #include "url/gurl.h" |
| 17 | 19 |
| 18 namespace { | 20 #if defined(OS_ANDROID) |
| 19 | 21 #include "net/android/network_library.h" |
| 20 // Maximum number of observations that can be held in the ObservationBuffer. | 22 #endif // OS_ANDROID |
| 21 const size_t kMaximumObservationsBufferSize = 500; | |
| 22 | |
| 23 } // namespace | |
| 24 | 23 |
| 25 namespace net { | 24 namespace net { |
| 26 | 25 |
| 26 const size_t NetworkQualityEstimator::kMaximumNetworkQualityCacheSize; | |
| 27 | |
| 28 const size_t NetworkQualityEstimator::kMaximumObservationsBufferSize; | |
| 29 | |
| 27 NetworkQualityEstimator::NetworkQualityEstimator() | 30 NetworkQualityEstimator::NetworkQualityEstimator() |
| 28 : NetworkQualityEstimator(false, false) { | 31 : NetworkQualityEstimator(false, false) { |
| 29 } | 32 } |
| 30 | 33 |
| 31 NetworkQualityEstimator::NetworkQualityEstimator( | 34 NetworkQualityEstimator::NetworkQualityEstimator( |
| 32 bool allow_local_host_requests_for_tests, | 35 bool allow_local_host_requests_for_tests, |
| 33 bool allow_smaller_responses_for_tests) | 36 bool allow_smaller_responses_for_tests) |
| 34 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 37 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
| 35 allow_small_responses_(allow_smaller_responses_for_tests), | 38 allow_small_responses_(allow_smaller_responses_for_tests), |
| 36 last_connection_change_(base::TimeTicks::Now()), | 39 last_connection_change_(base::TimeTicks::Now()), |
| 37 current_connection_type_(NetworkChangeNotifier::GetConnectionType()), | 40 current_network_id_( |
| 41 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | |
| 42 std::string())), | |
| 38 fastest_rtt_since_last_connection_change_(base::TimeDelta::Max()), | 43 fastest_rtt_since_last_connection_change_(base::TimeDelta::Max()), |
| 39 peak_kbps_since_last_connection_change_(0) { | 44 peak_kbps_since_last_connection_change_(0) { |
| 40 static_assert(kMinRequestDurationMicroseconds > 0, | 45 static_assert(kMinRequestDurationMicroseconds > 0, |
| 41 "Minimum request duration must be > 0"); | 46 "Minimum request duration must be > 0"); |
| 47 static_assert(kMaximumNetworkQualityCacheSize > 0, | |
| 48 "Size of the network quality cache must be > 0"); | |
| 49 | |
| 50 // This limit should not be increased unless the logic for removing the | |
| 51 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | |
| 52 static_assert(kMaximumNetworkQualityCacheSize <= 10, | |
| 53 "Size of the network quality cache must <= 10"); | |
| 42 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 54 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 55 current_network_id_ = GetCurrentNetworkID(); | |
| 43 } | 56 } |
| 44 | 57 |
| 45 NetworkQualityEstimator::~NetworkQualityEstimator() { | 58 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 46 DCHECK(thread_checker_.CalledOnValidThread()); | 59 DCHECK(thread_checker_.CalledOnValidThread()); |
| 47 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 60 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| 48 } | 61 } |
| 49 | 62 |
| 50 void NetworkQualityEstimator::NotifyDataReceived( | 63 void NetworkQualityEstimator::NotifyDataReceived( |
| 51 const URLRequest& request, | 64 const URLRequest& request, |
| 52 int64_t cumulative_prefilter_bytes_read, | 65 int64_t cumulative_prefilter_bytes_read, |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 | 142 |
| 130 kbps_observations_.AddObservation(Observation(kbps, now)); | 143 kbps_observations_.AddObservation(Observation(kbps, now)); |
| 131 } | 144 } |
| 132 } | 145 } |
| 133 } | 146 } |
| 134 | 147 |
| 135 void NetworkQualityEstimator::OnConnectionTypeChanged( | 148 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 136 NetworkChangeNotifier::ConnectionType type) { | 149 NetworkChangeNotifier::ConnectionType type) { |
| 137 DCHECK(thread_checker_.CalledOnValidThread()); | 150 DCHECK(thread_checker_.CalledOnValidThread()); |
| 138 if (fastest_rtt_since_last_connection_change_ != base::TimeDelta::Max()) { | 151 if (fastest_rtt_since_last_connection_change_ != base::TimeDelta::Max()) { |
| 139 switch (current_connection_type_) { | 152 switch (current_network_id_.type) { |
| 140 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 153 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 141 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 154 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", |
| 142 fastest_rtt_since_last_connection_change_); | 155 fastest_rtt_since_last_connection_change_); |
| 143 break; | 156 break; |
| 144 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 157 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
| 145 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Ethernet", | 158 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Ethernet", |
| 146 fastest_rtt_since_last_connection_change_); | 159 fastest_rtt_since_last_connection_change_); |
| 147 break; | 160 break; |
| 148 case NetworkChangeNotifier::CONNECTION_WIFI: | 161 case NetworkChangeNotifier::CONNECTION_WIFI: |
| 149 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Wifi", | 162 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Wifi", |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 163 break; | 176 break; |
| 164 case NetworkChangeNotifier::CONNECTION_NONE: | 177 case NetworkChangeNotifier::CONNECTION_NONE: |
| 165 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.None", | 178 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.None", |
| 166 fastest_rtt_since_last_connection_change_); | 179 fastest_rtt_since_last_connection_change_); |
| 167 break; | 180 break; |
| 168 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | 181 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: |
| 169 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Bluetooth", | 182 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Bluetooth", |
| 170 fastest_rtt_since_last_connection_change_); | 183 fastest_rtt_since_last_connection_change_); |
| 171 break; | 184 break; |
| 172 default: | 185 default: |
| 173 NOTREACHED(); | 186 NOTREACHED() << "Unexpected connection type = " |
| 187 << current_network_id_.type; | |
| 174 break; | 188 break; |
| 175 } | 189 } |
| 176 } | 190 } |
| 177 | 191 |
| 178 if (peak_kbps_since_last_connection_change_) { | 192 if (peak_kbps_since_last_connection_change_) { |
| 179 switch (current_connection_type_) { | 193 switch (current_network_id_.type) { |
| 180 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 194 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 181 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Unknown", | 195 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Unknown", |
| 182 peak_kbps_since_last_connection_change_); | 196 peak_kbps_since_last_connection_change_); |
| 183 break; | 197 break; |
| 184 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 198 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
| 185 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Ethernet", | 199 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Ethernet", |
| 186 peak_kbps_since_last_connection_change_); | 200 peak_kbps_since_last_connection_change_); |
| 187 break; | 201 break; |
| 188 case NetworkChangeNotifier::CONNECTION_WIFI: | 202 case NetworkChangeNotifier::CONNECTION_WIFI: |
| 189 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Wifi", | 203 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Wifi", |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 203 break; | 217 break; |
| 204 case NetworkChangeNotifier::CONNECTION_NONE: | 218 case NetworkChangeNotifier::CONNECTION_NONE: |
| 205 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.None", | 219 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.None", |
| 206 peak_kbps_since_last_connection_change_); | 220 peak_kbps_since_last_connection_change_); |
| 207 break; | 221 break; |
| 208 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | 222 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: |
| 209 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Bluetooth", | 223 UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Bluetooth", |
| 210 peak_kbps_since_last_connection_change_); | 224 peak_kbps_since_last_connection_change_); |
| 211 break; | 225 break; |
| 212 default: | 226 default: |
| 213 NOTREACHED(); | 227 NOTREACHED() << "Unexpected connection type = " |
| 228 << current_network_id_.type; | |
| 214 break; | 229 break; |
| 215 } | 230 } |
| 216 } | 231 } |
| 217 | 232 |
| 233 // Write the estimates of the previous network to the cache. | |
| 234 CacheNetworkQualityEstimate(); | |
| 235 | |
| 236 // Clear the local state. | |
| 218 last_connection_change_ = base::TimeTicks::Now(); | 237 last_connection_change_ = base::TimeTicks::Now(); |
| 219 peak_kbps_since_last_connection_change_ = 0; | 238 peak_kbps_since_last_connection_change_ = 0; |
| 220 fastest_rtt_since_last_connection_change_ = base::TimeDelta::Max(); | 239 fastest_rtt_since_last_connection_change_ = base::TimeDelta::Max(); |
| 221 kbps_observations_.Clear(); | 240 kbps_observations_.Clear(); |
| 222 rtt_msec_observations_.Clear(); | 241 rtt_msec_observations_.Clear(); |
| 223 current_connection_type_ = type; | 242 |
| 243 // Update the current network ID. | |
| 244 current_network_id_ = GetCurrentNetworkID(); | |
| 245 | |
| 246 // Read any cached estimates for the new network. | |
| 247 ReadCachedNetworkQualityEstimate(); | |
| 248 } | |
| 249 | |
| 250 size_t NetworkQualityEstimator::GetNetworkQualityCacheSizeForTests() const { | |
| 251 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 252 return cached_network_qualities_.size(); | |
| 224 } | 253 } |
| 225 | 254 |
| 226 NetworkQuality NetworkQualityEstimator::GetPeakEstimate() const { | 255 NetworkQuality NetworkQualityEstimator::GetPeakEstimate() const { |
| 227 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(thread_checker_.CalledOnValidThread()); |
| 228 | 257 |
| 229 return NetworkQuality(fastest_rtt_since_last_connection_change_, | 258 return NetworkQuality(fastest_rtt_since_last_connection_change_, |
| 230 peak_kbps_since_last_connection_change_); | 259 peak_kbps_since_last_connection_change_); |
| 231 } | 260 } |
| 232 | 261 |
| 233 size_t NetworkQualityEstimator::GetMaximumObservationBufferSizeForTests() | 262 size_t NetworkQualityEstimator::GetKbpsObservationBufferSizeForTests() const { |
| 234 const { | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
| 235 return kMaximumObservationsBufferSize; | 264 return kbps_observations_.Size(); |
| 236 } | 265 } |
| 237 | 266 |
| 238 bool NetworkQualityEstimator::VerifyBufferSizeForTests( | 267 size_t NetworkQualityEstimator::GetRTTObservationBufferSizeForTests() const { |
| 239 size_t expected_size) const { | 268 DCHECK(thread_checker_.CalledOnValidThread()); |
| 240 return kbps_observations_.Size() == expected_size && | 269 return rtt_msec_observations_.Size(); |
| 241 rtt_msec_observations_.Size() == expected_size; | |
| 242 } | 270 } |
| 243 | 271 |
| 244 NetworkQualityEstimator::Observation::Observation(int32_t value, | 272 NetworkQualityEstimator::Observation::Observation(int32_t value, |
| 245 base::TimeTicks timestamp) | 273 base::TimeTicks timestamp) |
| 246 : value(value), timestamp(timestamp) { | 274 : value(value), timestamp(timestamp) { |
| 247 DCHECK_GE(value, 0); | 275 DCHECK_GE(value, 0); |
| 248 DCHECK(!timestamp.is_null()); | 276 DCHECK(!timestamp.is_null()); |
| 249 } | 277 } |
| 250 | 278 |
| 251 NetworkQualityEstimator::Observation::~Observation() { | 279 NetworkQualityEstimator::Observation::~Observation() { |
| 252 } | 280 } |
| 253 | 281 |
| 254 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer() { | 282 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer() { |
| 255 static_assert(kMaximumObservationsBufferSize > 0U, | 283 static_assert(kMaximumObservationsBufferSize > 0U, |
| 256 "Minimum size of observation buffer must be > 0"); | 284 "Minimum size of observation buffer must be > 0"); |
| 257 } | 285 } |
| 258 | 286 |
| 259 NetworkQualityEstimator::ObservationBuffer::~ObservationBuffer() { | 287 NetworkQualityEstimator::ObservationBuffer::~ObservationBuffer() { |
| 260 } | 288 } |
| 261 | 289 |
| 262 void NetworkQualityEstimator::ObservationBuffer::AddObservation( | 290 void NetworkQualityEstimator::ObservationBuffer::AddObservation( |
| 263 const Observation& observation) { | 291 const Observation& observation) { |
| 264 DCHECK_LE(observations_.size(), kMaximumObservationsBufferSize); | 292 DCHECK_LE(observations_.size(), |
| 293 NetworkQualityEstimator::kMaximumObservationsBufferSize); | |
|
pauljensen
2015/06/22 18:39:52
Is NetworkQualityEstimator:: really necessary? Dit
tbansal1
2015/06/22 20:28:25
Its not really needed in this file but only in the
| |
| 265 // Evict the oldest element if the buffer is already full. | 294 // Evict the oldest element if the buffer is already full. |
| 266 if (observations_.size() == kMaximumObservationsBufferSize) | 295 if (observations_.size() == |
| 296 NetworkQualityEstimator::kMaximumObservationsBufferSize) | |
| 267 observations_.pop_front(); | 297 observations_.pop_front(); |
| 268 | 298 |
| 269 observations_.push_back(observation); | 299 observations_.push_back(observation); |
| 270 DCHECK_LE(observations_.size(), kMaximumObservationsBufferSize); | 300 DCHECK_LE(observations_.size(), |
| 301 NetworkQualityEstimator::kMaximumObservationsBufferSize); | |
| 271 } | 302 } |
| 272 | 303 |
| 273 size_t NetworkQualityEstimator::ObservationBuffer::Size() const { | 304 size_t NetworkQualityEstimator::ObservationBuffer::Size() const { |
| 274 return observations_.size(); | 305 return observations_.size(); |
| 275 } | 306 } |
| 276 | 307 |
| 277 void NetworkQualityEstimator::ObservationBuffer::Clear() { | 308 void NetworkQualityEstimator::ObservationBuffer::Clear() { |
| 278 observations_.clear(); | 309 observations_.clear(); |
| 279 DCHECK(observations_.empty()); | 310 DCHECK(observations_.empty()); |
| 280 } | 311 } |
| 281 | 312 |
| 313 NetworkQualityEstimator::NetworkID | |
| 314 NetworkQualityEstimator::GetCurrentNetworkID() const { | |
| 315 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class | |
| 316 // that overrides this method on the Android platform. | |
| 317 | |
| 318 // It is possible that the connection type changed between when | |
| 319 // GetConnectionType() was called and when the API to determine the | |
| 320 // network name was called. Check if that happened and retry until the | |
| 321 // connection type stabilizes. This is an imperfect solution but should | |
| 322 // capture majority of cases, and should not significantly affect estimates | |
| 323 // (that are approximate to begin with). | |
| 324 while (true) { | |
| 325 NetworkQualityEstimator::NetworkID network_id( | |
| 326 NetworkChangeNotifier::GetConnectionType(), std::string()); | |
| 327 | |
| 328 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 329 | |
| 330 switch (network_id.type) { | |
| 331 case NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN: | |
| 332 case NetworkChangeNotifier::ConnectionType::CONNECTION_NONE: | |
| 333 case NetworkChangeNotifier::ConnectionType::CONNECTION_BLUETOOTH: | |
| 334 case NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET: | |
| 335 break; | |
| 336 case NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI: | |
| 337 #if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) | |
| 338 network_id.id = GetWifiSSID(); | |
|
pauljensen
2015/06/22 18:39:52
We should implement this for windows. It should b
tbansal1
2015/06/22 20:28:25
Filed crbug.com/503235
| |
| 339 break; | |
| 340 #else | |
| 341 break; | |
| 342 #endif | |
| 343 case NetworkChangeNotifier::ConnectionType::CONNECTION_2G: | |
| 344 case NetworkChangeNotifier::ConnectionType::CONNECTION_3G: | |
| 345 case NetworkChangeNotifier::ConnectionType::CONNECTION_4G: | |
| 346 #if defined(OS_ANDROID) | |
| 347 network_id.id = android::GetTelephonyNetworkOperator(); | |
| 348 break; | |
| 349 #else | |
| 350 break; | |
| 351 #endif | |
| 352 default: | |
| 353 NOTREACHED() << "Unexpected connection type = " << network_id.type; | |
| 354 } | |
| 355 | |
| 356 if (network_id.type == NetworkChangeNotifier::GetConnectionType()) | |
| 357 return network_id; | |
| 358 } | |
| 359 NOTREACHED(); | |
| 360 } | |
| 361 | |
| 362 bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() { | |
| 363 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 364 | |
| 365 // If the network name is unavailable, caching should not be performed. | |
| 366 if (current_network_id_.id.empty()) | |
| 367 return false; | |
| 368 | |
| 369 CachedNetworkQualities::iterator it = | |
| 370 cached_network_qualities_.find(current_network_id_); | |
| 371 if (it != cached_network_qualities_.end()) { | |
| 372 // TOOD(tbansal): Populate these values back into the median computing | |
| 373 // algorithm. | |
| 374 // Add UMA to record how frequently matches happen. | |
|
pauljensen
2015/06/22 18:39:52
Add a "TODO(tbansal):" here and the next line
tbansal1
2015/06/22 20:28:26
Done.
| |
| 375 // Ensure that the estimates read are non-zero before populating them into | |
| 376 // the median computing algorithm. | |
| 377 peak_kbps_since_last_connection_change_ = | |
| 378 it->second->network_quality().downstream_throughput_kbps(); | |
| 379 fastest_rtt_since_last_connection_change_ = | |
| 380 it->second->network_quality().rtt(); | |
| 381 return true; | |
| 382 } | |
| 383 return false; | |
| 384 } | |
| 385 | |
| 386 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | |
| 387 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 388 DCHECK_LE(cached_network_qualities_.size(), kMaximumNetworkQualityCacheSize); | |
| 389 | |
| 390 // If the network name is unavailable, caching should not be performed. | |
| 391 if (current_network_id_.id.empty()) | |
| 392 return; | |
| 393 | |
| 394 // TODO(tbansal): The following variables should be initialized using the | |
| 395 // median values reported by the NetworkQualityEstimator. | |
| 396 int median_kbps = peak_kbps_since_last_connection_change_; | |
| 397 base::TimeDelta median_rtt = fastest_rtt_since_last_connection_change_; | |
| 398 | |
| 399 // If this network is already in the cache, overwrite that entry. | |
| 400 CachedNetworkQualities::iterator it = | |
| 401 cached_network_qualities_.find(current_network_id_); | |
| 402 if (it != cached_network_qualities_.end()) { | |
| 403 (it->second)->UpdateNetworkQuality(median_kbps, median_rtt); | |
| 404 return; | |
| 405 } | |
| 406 | |
| 407 if (cached_network_qualities_.size() == kMaximumNetworkQualityCacheSize) { | |
| 408 // Remove the oldest entry. | |
| 409 CachedNetworkQualities::iterator oldest_entry_iterator = | |
| 410 cached_network_qualities_.begin(); | |
| 411 | |
| 412 for (CachedNetworkQualities::iterator it = | |
| 413 cached_network_qualities_.begin(); | |
| 414 it != cached_network_qualities_.end(); ++it) { | |
| 415 if ((it->second)->OlderThan(*(oldest_entry_iterator->second.get()))) | |
| 416 oldest_entry_iterator = it; | |
| 417 } | |
| 418 cached_network_qualities_.erase(oldest_entry_iterator); | |
| 419 } | |
| 420 | |
| 421 DCHECK_LT(cached_network_qualities_.size(), kMaximumNetworkQualityCacheSize); | |
| 422 cached_network_qualities_.insert(std::make_pair( | |
| 423 current_network_id_, make_scoped_ptr(new CachedNetworkQuality( | |
| 424 NetworkQuality(median_rtt, median_kbps))))); | |
| 425 DCHECK_LE(cached_network_qualities_.size(), kMaximumNetworkQualityCacheSize); | |
| 426 } | |
| 427 | |
| 428 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | |
| 429 const NetworkQuality& network_quality) | |
| 430 : last_update_time_(base::TimeTicks::Now()), | |
| 431 network_quality_(network_quality) { | |
| 432 } | |
| 433 | |
| 434 NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() { | |
| 435 } | |
| 436 | |
| 437 bool NetworkQualityEstimator::CachedNetworkQuality::OlderThan( | |
| 438 const CachedNetworkQuality& cached_network_quality) const { | |
| 439 return last_update_time_ < cached_network_quality.last_update_time_; | |
| 440 } | |
| 441 | |
| 442 void NetworkQualityEstimator::CachedNetworkQuality::UpdateNetworkQuality( | |
| 443 int32_t median_kbps, | |
| 444 const base::TimeDelta& median_rtt) { | |
| 445 DCHECK_GE(median_kbps, 0); | |
| 446 DCHECK_GE(median_rtt, base::TimeDelta()); | |
| 447 last_update_time_ = base::TimeTicks::Now(); | |
| 448 | |
| 449 network_quality_ = NetworkQuality(median_rtt, median_kbps); | |
| 450 } | |
| 451 | |
| 282 } // namespace net | 452 } // namespace net |
| OLD | NEW |