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/nqe/network_quality_estimator.h" | 5 #include "net/nqe/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/metrics/histogram_base.h" | 17 #include "base/metrics/histogram_base.h" |
| 18 #include "base/metrics/sparse_histogram.h" | |
| 19 #include "base/rand_util.h" | |
| 18 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
| 19 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
| 21 #include "base/time/default_tick_clock.h" | 23 #include "base/time/default_tick_clock.h" |
| 22 #include "base/trace_event/trace_event.h" | 24 #include "base/trace_event/trace_event.h" |
| 23 #include "build/build_config.h" | 25 #include "build/build_config.h" |
| 24 #include "net/base/load_flags.h" | 26 #include "net/base/load_flags.h" |
| 25 #include "net/base/load_timing_info.h" | 27 #include "net/base/load_timing_info.h" |
| 26 #include "net/base/network_interfaces.h" | 28 #include "net/base/network_interfaces.h" |
| 27 #include "net/base/url_util.h" | 29 #include "net/base/url_util.h" |
| 30 #include "net/http/http_status_code.h" | |
| 28 #include "net/nqe/socket_watcher_factory.h" | 31 #include "net/nqe/socket_watcher_factory.h" |
| 29 #include "net/nqe/throughput_analyzer.h" | 32 #include "net/nqe/throughput_analyzer.h" |
| 30 #include "net/url_request/url_request.h" | 33 #include "net/url_request/url_request.h" |
| 34 #include "net/url_request/url_request_status.h" | |
| 31 #include "url/gurl.h" | 35 #include "url/gurl.h" |
| 32 | 36 |
| 33 #if defined(OS_ANDROID) | 37 #if defined(OS_ANDROID) |
| 34 #include "net/android/network_library.h" | 38 #include "net/android/network_library.h" |
| 35 #endif // OS_ANDROID | 39 #endif // OS_ANDROID |
| 36 | 40 |
| 37 namespace { | 41 namespace { |
| 38 | 42 |
| 39 // Default value of the half life (in seconds) for computing time weighted | 43 // Default value of the half life (in seconds) for computing time weighted |
| 40 // percentiles. Every half life, the weight of all observations reduces by | 44 // percentiles. Every half life, the weight of all observations reduces by |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 | 138 |
| 135 bool GetValueForVariationParam( | 139 bool GetValueForVariationParam( |
| 136 const std::map<std::string, std::string>& variation_params, | 140 const std::map<std::string, std::string>& variation_params, |
| 137 const std::string& parameter_name, | 141 const std::string& parameter_name, |
| 138 int32_t* variations_value) { | 142 int32_t* variations_value) { |
| 139 const auto it = variation_params.find(parameter_name); | 143 const auto it = variation_params.find(parameter_name); |
| 140 return it != variation_params.end() && | 144 return it != variation_params.end() && |
| 141 base::StringToInt(it->second, variations_value); | 145 base::StringToInt(it->second, variations_value); |
| 142 } | 146 } |
| 143 | 147 |
| 148 // Returns the variation value for |parameter_name|. If the value is | |
| 149 // unavailable, |default_value| is returned. | |
| 150 double GetDoubleValueForVariationParamWithDefaultValue( | |
| 151 const std::map<std::string, std::string>& variation_params, | |
| 152 const std::string& parameter_name, | |
| 153 double default_value) { | |
| 154 const auto it = variation_params.find(parameter_name); | |
| 155 if (it == variation_params.end()) | |
| 156 return default_value; | |
| 157 | |
| 158 double variations_value = default_value; | |
| 159 if (!base::StringToDouble(it->second, &variations_value)) | |
| 160 return default_value; | |
| 161 return variations_value; | |
| 162 } | |
| 163 | |
| 144 // Returns the algorithm that should be used for computing effective connection | 164 // Returns the algorithm that should be used for computing effective connection |
| 145 // type based on field trial params. Returns an empty string if a valid | 165 // type based on field trial params. Returns an empty string if a valid |
| 146 // algorithm paramter is not present in the field trial params. | 166 // algorithm paramter is not present in the field trial params. |
| 147 std::string GetEffectiveConnectionTypeAlgorithm( | 167 std::string GetEffectiveConnectionTypeAlgorithm( |
| 148 const std::map<std::string, std::string>& variation_params) { | 168 const std::map<std::string, std::string>& variation_params) { |
| 149 const auto it = variation_params.find("effective_connection_type_algorithm"); | 169 const auto it = variation_params.find("effective_connection_type_algorithm"); |
| 150 if (it == variation_params.end()) | 170 if (it == variation_params.end()) |
| 151 return std::string(); | 171 return std::string(); |
| 152 return it->second; | 172 return it->second; |
| 153 } | 173 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 181 static const char* const kSuffixes[] = { | 201 static const char* const kSuffixes[] = { |
| 182 "0_20", "20_60", "60_140", "140_300", "300_620", | 202 "0_20", "20_60", "60_140", "140_300", "300_620", |
| 183 "620_1260", "1260_2540", "2540_5100", "5100_Infinity"}; | 203 "620_1260", "1260_2540", "2540_5100", "5100_Infinity"}; |
| 184 for (size_t i = 0; i < arraysize(kSuffixes) - 1; ++i) { | 204 for (size_t i = 0; i < arraysize(kSuffixes) - 1; ++i) { |
| 185 if (rtt_milliseconds <= static_cast<float>((20 * (2 << i) - 20))) | 205 if (rtt_milliseconds <= static_cast<float>((20 * (2 << i) - 20))) |
| 186 return kSuffixes[i]; | 206 return kSuffixes[i]; |
| 187 } | 207 } |
| 188 return kSuffixes[arraysize(kSuffixes) - 1]; | 208 return kSuffixes[arraysize(kSuffixes) - 1]; |
| 189 } | 209 } |
| 190 | 210 |
| 211 // The least significant kTrimBits of the metric will be discarded. Next, it | |
| 212 // will be rounded down so it fits within kBitsPerMetric bits. This implies | |
| 213 // that if the metric's value is more than 2^(kTrimBits + kBitsPerMetric), | |
| 214 // then it will be rounded down. | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
This is confusing. Can you please rephrase it. How
tbansal1
2016/07/01 00:16:00
Done.
| |
| 215 const int32_t kTrimBits = 5; | |
| 216 const int32_t kBitsPerMetric = 7; | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Add:
static_assert(31 > kBitsPerMetric * 4, "4 met
tbansal1
2016/07/01 00:16:00
Done.
| |
| 217 | |
| 218 // Trims the |metric| by removing the last kTrimBits, and then rounding down | |
| 219 // the |metric| such that the |metric| fits in kBitsPerMetric. | |
| 220 int32_t TrimAndRoundDown(int32_t metric) { | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Rename method to FitInKBitsPerMetricBits?
tbansal1
2016/07/01 00:16:00
Done.
| |
| 221 // Remove the last kTrimBits. This will allow the metric to fit within | |
| 222 // kBitsPerMetric while losing only the least significant bits. | |
| 223 metric = metric >> kTrimBits; | |
| 224 if (metric >= (1 << kBitsPerMetric)) { | |
| 225 // Fit |metric| in kBitsPerMetric by rounding it down. | |
| 226 metric = (1 << kBitsPerMetric) - 1; | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Possible Refactor:
int32_t largest_value_using_kBi
tbansal1
2016/07/01 00:16:01
Done.
| |
| 227 } | |
| 228 DCHECK_EQ(0, metric >> kBitsPerMetric); | |
| 229 return metric; | |
| 230 } | |
| 231 | |
| 191 } // namespace | 232 } // namespace |
| 192 | 233 |
| 193 namespace net { | 234 namespace net { |
| 194 | 235 |
| 195 NetworkQualityEstimator::NetworkQualityEstimator( | 236 NetworkQualityEstimator::NetworkQualityEstimator( |
| 196 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | 237 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, |
| 197 const std::map<std::string, std::string>& variation_params) | 238 const std::map<std::string, std::string>& variation_params) |
| 198 : NetworkQualityEstimator(std::move(external_estimates_provider), | 239 : NetworkQualityEstimator(std::move(external_estimates_provider), |
| 199 variation_params, | 240 variation_params, |
| 200 false, | 241 false, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 223 effective_connection_type_recomputation_interval_( | 264 effective_connection_type_recomputation_interval_( |
| 224 base::TimeDelta::FromSeconds(15)), | 265 base::TimeDelta::FromSeconds(15)), |
| 225 last_connection_change_(tick_clock_->NowTicks()), | 266 last_connection_change_(tick_clock_->NowTicks()), |
| 226 current_network_id_( | 267 current_network_id_( |
| 227 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 268 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 228 std::string())), | 269 std::string())), |
| 229 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 270 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 230 rtt_observations_(weight_multiplier_per_second_), | 271 rtt_observations_(weight_multiplier_per_second_), |
| 231 external_estimate_provider_(std::move(external_estimates_provider)), | 272 external_estimate_provider_(std::move(external_estimates_provider)), |
| 232 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 273 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 274 correlation_logging_probability_( | |
| 275 GetDoubleValueForVariationParamWithDefaultValue( | |
| 276 variation_params, | |
| 277 "correlation_logging_probability", | |
| 278 0.0)), | |
| 233 weak_ptr_factory_(this) { | 279 weak_ptr_factory_(this) { |
| 234 static_assert(kDefaultHalfLifeSeconds > 0, | 280 static_assert(kDefaultHalfLifeSeconds > 0, |
| 235 "Default half life duration must be > 0"); | 281 "Default half life duration must be > 0"); |
| 236 static_assert(kMaximumNetworkQualityCacheSize > 0, | 282 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 237 "Size of the network quality cache must be > 0"); | 283 "Size of the network quality cache must be > 0"); |
| 238 // This limit should not be increased unless the logic for removing the | 284 // This limit should not be increased unless the logic for removing the |
| 239 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 285 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 240 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 286 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| 241 "Size of the network quality cache must <= 10"); | 287 "Size of the network quality cache must <= 10"); |
| 242 // None of the algorithms can have an empty name. | 288 // None of the algorithms can have an empty name. |
| 243 DCHECK(algorithm_name_to_enum_.end() == | 289 DCHECK(algorithm_name_to_enum_.end() == |
| 244 algorithm_name_to_enum_.find(std::string())); | 290 algorithm_name_to_enum_.find(std::string())); |
| 245 | 291 |
| 246 DCHECK_EQ(algorithm_name_to_enum_.size(), | 292 DCHECK_EQ(algorithm_name_to_enum_.size(), |
| 247 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: | 293 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: |
| 248 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); | 294 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); |
| 249 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: | 295 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: |
| 250 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, | 296 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, |
| 251 effective_connection_type_algorithm_); | 297 effective_connection_type_algorithm_); |
| 298 DCHECK_LE(0.0, correlation_logging_probability_); | |
| 299 DCHECK_GE(1.0, correlation_logging_probability_); | |
| 252 | 300 |
| 253 ObtainOperatingParams(variation_params); | 301 ObtainOperatingParams(variation_params); |
| 254 ObtainEffectiveConnectionTypeModelParams(variation_params); | 302 ObtainEffectiveConnectionTypeModelParams(variation_params); |
| 255 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 303 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 256 if (external_estimate_provider_) { | 304 if (external_estimate_provider_) { |
| 257 RecordExternalEstimateProviderMetrics( | 305 RecordExternalEstimateProviderMetrics( |
| 258 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 306 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
| 259 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 307 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
| 260 } else { | 308 } else { |
| 261 RecordExternalEstimateProviderMetrics( | 309 RecordExternalEstimateProviderMetrics( |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 | 531 |
| 484 LoadTimingInfo load_timing_info; | 532 LoadTimingInfo load_timing_info; |
| 485 request.GetLoadTimingInfo(&load_timing_info); | 533 request.GetLoadTimingInfo(&load_timing_info); |
| 486 | 534 |
| 487 // If the load timing info is unavailable, it probably means that the request | 535 // If the load timing info is unavailable, it probably means that the request |
| 488 // did not go over the network. | 536 // did not go over the network. |
| 489 if (load_timing_info.send_start.is_null() || | 537 if (load_timing_info.send_start.is_null() || |
| 490 load_timing_info.receive_headers_end.is_null()) { | 538 load_timing_info.receive_headers_end.is_null()) { |
| 491 return; | 539 return; |
| 492 } | 540 } |
| 541 DCHECK(!request.response_info().was_cached); | |
| 493 | 542 |
| 494 // Duration between when the resource was requested and when the response | 543 // Duration between when the resource was requested and when the response |
| 495 // headers were received. | 544 // headers were received. |
| 496 base::TimeDelta observed_http_rtt = | 545 base::TimeDelta observed_http_rtt = |
| 497 load_timing_info.receive_headers_end - load_timing_info.send_start; | 546 load_timing_info.receive_headers_end - load_timing_info.send_start; |
| 498 DCHECK_GE(observed_http_rtt, base::TimeDelta()); | 547 DCHECK_GE(observed_http_rtt, base::TimeDelta()); |
| 499 if (observed_http_rtt < peak_network_quality_.http_rtt()) { | 548 if (observed_http_rtt < peak_network_quality_.http_rtt()) { |
| 500 peak_network_quality_ = nqe::internal::NetworkQuality( | 549 peak_network_quality_ = nqe::internal::NetworkQuality( |
| 501 observed_http_rtt, peak_network_quality_.transport_rtt(), | 550 observed_http_rtt, peak_network_quality_.transport_rtt(), |
| 502 peak_network_quality_.downstream_throughput_kbps()); | 551 peak_network_quality_.downstream_throughput_kbps()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 void NetworkQualityEstimator::NotifyRequestCompleted( | 626 void NetworkQualityEstimator::NotifyRequestCompleted( |
| 578 const URLRequest& request) { | 627 const URLRequest& request) { |
| 579 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 628 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 580 "NetworkQualityEstimator::NotifyRequestCompleted"); | 629 "NetworkQualityEstimator::NotifyRequestCompleted"); |
| 581 DCHECK(thread_checker_.CalledOnValidThread()); | 630 DCHECK(thread_checker_.CalledOnValidThread()); |
| 582 | 631 |
| 583 if (!RequestSchemeIsHTTPOrHTTPS(request)) | 632 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
| 584 return; | 633 return; |
| 585 | 634 |
| 586 throughput_analyzer_->NotifyRequestCompleted(request); | 635 throughput_analyzer_->NotifyRequestCompleted(request); |
| 636 RecordCorrelationMetric(request); | |
| 637 } | |
| 638 | |
| 639 void NetworkQualityEstimator::RecordCorrelationMetric( | |
| 640 const URLRequest& request) const { | |
| 641 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 642 | |
| 643 // The histogram is recorded with probability | |
| 644 // |correlation_logging_probability_| to reduce overhead. | |
| 645 if (base::RandDouble() >= correlation_logging_probability_) | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Shouldn't this be base::RandDouble() <= correlatio
tbansal1
2016/07/01 00:16:00
No. Say correlation_logging_probability_ is 1.0. T
Not at Google. Contact bengr
2016/07/01 18:26:26
Misread as condition to execute below. You are rig
| |
| 646 return; | |
| 647 | |
| 648 if (request.response_info().was_cached) | |
| 649 return; | |
| 650 LoadTimingInfo load_timing_info; | |
| 651 request.GetLoadTimingInfo(&load_timing_info); | |
| 652 | |
| 653 // If the load timing info is unavailable, it probably means that the request | |
| 654 // did not go over the network. | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Could this be replaced with request->response_info
tbansal1
2016/07/01 00:16:01
Done.
| |
| 655 if (load_timing_info.send_start.is_null() || | |
| 656 load_timing_info.receive_headers_end.is_null()) { | |
| 657 return; | |
| 658 } | |
| 659 | |
| 660 // Record UMA only for successful requests that have completed. | |
| 661 if (!request.status().is_success() || request.status().is_io_pending()) | |
| 662 return; | |
| 663 if (request.GetResponseCode() != HTTP_OK) | |
| 664 return; | |
| 665 if (load_timing_info.receive_headers_end < last_main_frame_request_) | |
| 666 return; | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Nit: Add new line.
tbansal1
2016/07/01 00:16:00
Done.
| |
| 667 const base::TimeTicks now = tick_clock_->NowTicks(); | |
| 668 // Record UMA only for requests that started recently. | |
| 669 if (now - last_main_frame_request_ > base::TimeDelta::FromSeconds(15)) | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Why ignore older requests?
tbansal1
2016/07/01 00:16:00
It is possible that network quality was recorded a
Not at Google. Contact bengr
2016/07/01 18:26:26
Acknowledged.
| |
| 670 return; | |
| 671 | |
| 672 DCHECK_GE(now, load_timing_info.send_start); | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Not sure this is necessary.
tbansal1
2016/07/01 00:16:01
It checks that we are not adding negative values t
Not at Google. Contact bengr
2016/07/01 18:26:26
Acknowledged.
| |
| 673 | |
| 674 // Histogram samples are 32-bit in size with first bit reserved for sign. | |
| 675 // Four metrics will be recorded per sample. | |
| 676 DCHECK_GE(31, kBitsPerMetric * 4); | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Prefer replacing with static assert above where kB
tbansal1
2016/07/01 00:16:01
Done.
| |
| 677 | |
| 678 const int32_t transport_rtt_milliseconds = | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Does it help to extract estimated_quality_at_last_
tbansal1
2016/07/01 00:16:00
I am not sure. I wanted to declare it as a const v
| |
| 679 estimated_quality_at_last_main_frame_.transport_rtt() != | |
| 680 nqe::internal::InvalidRTT() | |
| 681 ? TrimAndRoundDown( | |
| 682 estimated_quality_at_last_main_frame_.transport_rtt() | |
| 683 .InMilliseconds()) | |
| 684 : 0; | |
| 685 | |
| 686 const int32_t http_rtt_milliseconds = | |
| 687 estimated_quality_at_last_main_frame_.http_rtt() != | |
| 688 nqe::internal::InvalidRTT() | |
| 689 ? TrimAndRoundDown(estimated_quality_at_last_main_frame_.http_rtt() | |
| 690 .InMilliseconds()) | |
| 691 : 0; | |
| 692 | |
| 693 const int32_t downstream_throughput_kbps = | |
| 694 estimated_quality_at_last_main_frame_.downstream_throughput_kbps() != | |
| 695 nqe::internal::kInvalidThroughput | |
| 696 ? TrimAndRoundDown(estimated_quality_at_last_main_frame_ | |
| 697 .downstream_throughput_kbps()) | |
| 698 : 0; | |
| 699 | |
| 700 const int32_t resource_load_time_milliseconds = | |
| 701 TrimAndRoundDown((now - load_timing_info.send_start).InMilliseconds()); | |
| 702 | |
| 703 // First 32 - (4* kBitsPerMetric) of the sample are unset. Next | |
| 704 // kBitsPerMetric of the sample contain |transport_rtt_milliseconds|. | |
| 705 // Next kBitsPerMetric contain |http_rtt_milliseconds|. Next kBitsPerMetric | |
| 706 // contain |downstream_throughput_kbps|. And, the last kBitsPerMetric | |
| 707 // contain |resource_load_time_milliseconds|. | |
| 708 int32_t sample = transport_rtt_milliseconds; | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Suggest adding DCHECK_EQ(0, transport_rtt_millisec
tbansal1
2016/07/01 00:16:00
Done.
| |
| 709 sample = (sample << kBitsPerMetric) + http_rtt_milliseconds; | |
|
Not at Google. Contact bengr
2016/06/30 17:49:44
Minor: | seems prefereable to +.
tbansal1
2016/07/01 00:16:00
Done.
| |
| 710 sample = (sample << kBitsPerMetric) + downstream_throughput_kbps; | |
| 711 sample = (sample << kBitsPerMetric) + resource_load_time_milliseconds; | |
| 712 | |
| 713 UMA_HISTOGRAM_SPARSE_SLOWLY("NQE.Correlation.ResourceLoadTime", sample); | |
| 587 } | 714 } |
| 588 | 715 |
| 589 void NetworkQualityEstimator::NotifyURLRequestDestroyed( | 716 void NetworkQualityEstimator::NotifyURLRequestDestroyed( |
| 590 const URLRequest& request) { | 717 const URLRequest& request) { |
| 591 DCHECK(thread_checker_.CalledOnValidThread()); | 718 DCHECK(thread_checker_.CalledOnValidThread()); |
| 592 | 719 |
| 593 NotifyRequestCompleted(request); | 720 NotifyRequestCompleted(request); |
| 594 } | 721 } |
| 595 | 722 |
| 596 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { | 723 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1289 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1416 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1290 DCHECK(thread_checker_.CalledOnValidThread()); | 1417 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1291 | 1418 |
| 1292 // TODO(tbansal): Add hysteresis in the notification. | 1419 // TODO(tbansal): Add hysteresis in the notification. |
| 1293 FOR_EACH_OBSERVER( | 1420 FOR_EACH_OBSERVER( |
| 1294 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1421 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1295 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1422 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1296 } | 1423 } |
| 1297 | 1424 |
| 1298 } // namespace net | 1425 } // namespace net |
| OLD | NEW |