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> |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 } | 150 } |
| 151 NOTREACHED(); | 151 NOTREACHED(); |
| 152 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; | 152 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; |
| 153 } | 153 } |
| 154 | 154 |
| 155 // Returns true if the scheme of the |request| is either HTTP or HTTPS. | 155 // Returns true if the scheme of the |request| is either HTTP or HTTPS. |
| 156 bool RequestSchemeIsHTTPOrHTTPS(const net::URLRequest& request) { | 156 bool RequestSchemeIsHTTPOrHTTPS(const net::URLRequest& request) { |
| 157 return request.url().is_valid() && request.url().SchemeIsHTTPOrHTTPS(); | 157 return request.url().is_valid() && request.url().SchemeIsHTTPOrHTTPS(); |
| 158 } | 158 } |
| 159 | 159 |
| 160 // Returns the suffix of the histogram that should be used for recording the | |
| 161 // accuracy when the observed RTT is |observed_rtt|. The width of the intervals | |
| 162 // are in exponentially increasing order. | |
| 163 std::string GetHistogramSuffixObservedRTT(const base::TimeDelta& observed_rtt) { | |
| 164 const float rtt_milliseconds = observed_rtt.InMillisecondsF(); | |
| 165 DCHECK_GE(rtt_milliseconds, 0); | |
| 166 | |
| 167 // The values here should remain synchronized with the suffixes specified in | |
| 168 // histograms.xml. | |
| 169 static const char* const kSuffixes[] = { | |
| 170 "0_20", "20_60", "60_140", "140_300", "300_620", | |
| 171 "620_1260", "1260_2540", "2540_5100", "5100_Infinity"}; | |
| 172 for (size_t i = 0; i < arraysize(kSuffixes) - 1; ++i) { | |
| 173 if (rtt_milliseconds <= static_cast<float>((20 * (2 << i) - 20))) | |
| 174 return kSuffixes[i]; | |
| 175 } | |
| 176 return kSuffixes[arraysize(kSuffixes) - 1]; | |
| 177 } | |
| 178 | |
| 160 } // namespace | 179 } // namespace |
| 161 | 180 |
| 162 namespace net { | 181 namespace net { |
| 163 | 182 |
| 164 // SocketWatcher implements SocketPerformanceWatcher, and notifies | 183 // SocketWatcher implements SocketPerformanceWatcher, and notifies |
| 165 // NetworkQualityEstimator of various socket performance events. SocketWatcher | 184 // NetworkQualityEstimator of various socket performance events. SocketWatcher |
| 166 // is not thread-safe. | 185 // is not thread-safe. |
| 167 class NetworkQualityEstimator::SocketWatcher : public SocketPerformanceWatcher { | 186 class NetworkQualityEstimator::SocketWatcher : public SocketPerformanceWatcher { |
| 168 public: | 187 public: |
| 169 SocketWatcher( | 188 SocketWatcher( |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 AddDefaultEstimates(); | 308 AddDefaultEstimates(); |
| 290 | 309 |
| 291 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( | 310 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( |
| 292 base::ThreadTaskRunnerHandle::Get(), | 311 base::ThreadTaskRunnerHandle::Get(), |
| 293 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, | 312 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, |
| 294 base::Unretained(this)), | 313 base::Unretained(this)), |
| 295 use_localhost_requests_, use_smaller_responses_for_tests)); | 314 use_localhost_requests_, use_smaller_responses_for_tests)); |
| 296 | 315 |
| 297 watcher_factory_.reset(new SocketWatcherFactory( | 316 watcher_factory_.reset(new SocketWatcherFactory( |
| 298 base::ThreadTaskRunnerHandle::Get(), weak_ptr_factory_.GetWeakPtr())); | 317 base::ThreadTaskRunnerHandle::Get(), weak_ptr_factory_.GetWeakPtr())); |
| 318 | |
| 319 // Record accuracy at 3 different intervals. The values used here must remain | |
| 320 // in sync with the suffixes specified in | |
| 321 // tools/metrics/histograms/histograms.xml. | |
| 322 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); | |
| 323 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); | |
| 324 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); | |
| 299 } | 325 } |
| 300 | 326 |
| 301 void NetworkQualityEstimator::ObtainOperatingParams( | 327 void NetworkQualityEstimator::ObtainOperatingParams( |
| 302 const std::map<std::string, std::string>& variation_params) { | 328 const std::map<std::string, std::string>& variation_params) { |
| 303 DCHECK(thread_checker_.CalledOnValidThread()); | 329 DCHECK(thread_checker_.CalledOnValidThread()); |
| 304 | 330 |
| 305 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | 331 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { |
| 306 NetworkChangeNotifier::ConnectionType type = | 332 NetworkChangeNotifier::ConnectionType type = |
| 307 static_cast<NetworkChangeNotifier::ConnectionType>(i); | 333 static_cast<NetworkChangeNotifier::ConnectionType>(i); |
| 308 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); | 334 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 throughput_observation); | 450 throughput_observation); |
| 425 NotifyObserversOfThroughput(throughput_observation); | 451 NotifyObserversOfThroughput(throughput_observation); |
| 426 } | 452 } |
| 427 } | 453 } |
| 428 | 454 |
| 429 NetworkQualityEstimator::~NetworkQualityEstimator() { | 455 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 430 DCHECK(thread_checker_.CalledOnValidThread()); | 456 DCHECK(thread_checker_.CalledOnValidThread()); |
| 431 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 457 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| 432 } | 458 } |
| 433 | 459 |
| 460 const std::vector<base::TimeDelta>& | |
| 461 NetworkQualityEstimator::GetAccuracyRecordingIntervals() const { | |
| 462 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 463 return accuracy_recording_intervals_; | |
| 464 } | |
| 465 | |
| 434 void NetworkQualityEstimator::NotifyStartTransaction( | 466 void NetworkQualityEstimator::NotifyStartTransaction( |
| 435 const URLRequest& request) { | 467 const URLRequest& request) { |
| 436 DCHECK(thread_checker_.CalledOnValidThread()); | 468 DCHECK(thread_checker_.CalledOnValidThread()); |
| 437 | 469 |
| 438 if (!RequestSchemeIsHTTPOrHTTPS(request)) | 470 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
| 439 return; | 471 return; |
| 440 | 472 |
| 441 throughput_analyzer_->NotifyStartTransaction(request); | 473 throughput_analyzer_->NotifyStartTransaction(request); |
| 442 } | 474 } |
| 443 | 475 |
| 444 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { | 476 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { |
| 445 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 477 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 446 "NetworkQualityEstimator::NotifyHeadersReceived"); | 478 "NetworkQualityEstimator::NotifyHeadersReceived"); |
| 447 DCHECK(thread_checker_.CalledOnValidThread()); | 479 DCHECK(thread_checker_.CalledOnValidThread()); |
| 448 | 480 |
| 449 if (!RequestSchemeIsHTTPOrHTTPS(request) || | 481 if (!RequestSchemeIsHTTPOrHTTPS(request) || |
| 450 !RequestProvidesRTTObservation(request)) { | 482 !RequestProvidesRTTObservation(request)) { |
| 451 return; | 483 return; |
| 452 } | 484 } |
| 453 | 485 |
| 454 // Update |estimated_median_network_quality_| if this is a main frame request. | 486 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 487 | |
| 488 // Update |estimated_quality_at_last_main_frame_| if this is a main frame | |
| 489 // request. | |
| 455 if (request.load_flags() & LOAD_MAIN_FRAME) { | 490 if (request.load_flags() & LOAD_MAIN_FRAME) { |
| 491 last_main_frame_request_ = now; | |
| 456 base::TimeDelta estimated_http_rtt; | 492 base::TimeDelta estimated_http_rtt; |
| 457 if (!GetHttpRTTEstimate(&estimated_http_rtt)) | 493 if (!GetHttpRTTEstimate(&estimated_http_rtt)) |
| 458 estimated_http_rtt = nqe::internal::InvalidRTT(); | 494 estimated_http_rtt = nqe::internal::InvalidRTT(); |
| 459 | 495 |
| 496 base::TimeDelta estimated_transport_rtt; | |
| 497 if (!GetTransportRTTEstimate(&estimated_transport_rtt)) | |
| 498 estimated_transport_rtt = nqe::internal::InvalidRTT(); | |
| 499 | |
| 460 int32_t downstream_throughput_kbps; | 500 int32_t downstream_throughput_kbps; |
| 461 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) | 501 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) |
| 462 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; | 502 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 463 | 503 |
| 464 estimated_median_network_quality_ = nqe::internal::NetworkQuality( | 504 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality( |
| 465 estimated_http_rtt, nqe::internal::InvalidRTT(), | 505 estimated_http_rtt, estimated_transport_rtt, |
| 466 downstream_throughput_kbps); | 506 downstream_throughput_kbps); |
| 467 | 507 |
| 468 RecordMetricsOnMainFrameRequest(); | 508 RecordMetricsOnMainFrameRequest(); |
| 509 | |
| 510 // Post the tasks which will run in the future and record the estimation | |
| 511 // accuracy based on the observations received between now and the time of | |
| 512 // task execution. Posting the task at different intervals makes it | |
| 513 // possible to measure the accuracy by comparing the estimate with the | |
| 514 // observations received over intervals of varying durations. | |
| 515 for (const base::TimeDelta& measuring_delay : | |
| 516 GetAccuracyRecordingIntervals()) { | |
| 517 base::MessageLoop::current()->task_runner()->PostDelayedTask( | |
| 518 FROM_HERE, | |
| 519 base::Bind(&NetworkQualityEstimator::RecordAccuracyAfterMainFrame, | |
| 520 weak_ptr_factory_.GetWeakPtr(), measuring_delay), | |
| 521 measuring_delay); | |
| 522 } | |
| 469 } | 523 } |
| 470 | 524 |
| 471 const base::TimeTicks now = tick_clock_->NowTicks(); | |
| 472 LoadTimingInfo load_timing_info; | 525 LoadTimingInfo load_timing_info; |
| 473 request.GetLoadTimingInfo(&load_timing_info); | 526 request.GetLoadTimingInfo(&load_timing_info); |
| 474 | 527 |
| 475 // If the load timing info is unavailable, it probably means that the request | 528 // If the load timing info is unavailable, it probably means that the request |
| 476 // did not go over the network. | 529 // did not go over the network. |
| 477 if (load_timing_info.send_start.is_null() || | 530 if (load_timing_info.send_start.is_null() || |
| 478 load_timing_info.receive_headers_end.is_null()) { | 531 load_timing_info.receive_headers_end.is_null()) { |
| 479 return; | 532 return; |
| 480 } | 533 } |
| 481 | 534 |
| 482 // Duration between when the resource was requested and when the response | 535 // Duration between when the resource was requested and when the response |
| 483 // headers were received. | 536 // headers were received. |
| 484 base::TimeDelta observed_http_rtt = | 537 base::TimeDelta observed_http_rtt = |
| 485 load_timing_info.receive_headers_end - load_timing_info.send_start; | 538 load_timing_info.receive_headers_end - load_timing_info.send_start; |
| 486 DCHECK_GE(observed_http_rtt, base::TimeDelta()); | 539 DCHECK_GE(observed_http_rtt, base::TimeDelta()); |
| 487 if (observed_http_rtt < peak_network_quality_.http_rtt()) { | 540 if (observed_http_rtt < peak_network_quality_.http_rtt()) { |
| 488 peak_network_quality_ = nqe::internal::NetworkQuality( | 541 peak_network_quality_ = nqe::internal::NetworkQuality( |
| 489 observed_http_rtt, peak_network_quality_.transport_rtt(), | 542 observed_http_rtt, peak_network_quality_.transport_rtt(), |
| 490 peak_network_quality_.downstream_throughput_kbps()); | 543 peak_network_quality_.downstream_throughput_kbps()); |
| 491 } | 544 } |
| 492 | 545 |
| 493 RttObservation http_rtt_observation( | 546 RttObservation http_rtt_observation( |
| 494 observed_http_rtt, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | 547 observed_http_rtt, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); |
| 495 rtt_observations_.AddObservation(http_rtt_observation); | 548 rtt_observations_.AddObservation(http_rtt_observation); |
| 496 NotifyObserversOfRTT(http_rtt_observation); | 549 NotifyObserversOfRTT(http_rtt_observation); |
| 497 | 550 |
| 498 // Compare the RTT observation with the estimated value and record it. | 551 // Compare the RTT observation with the estimated value and record it. |
| 499 if (estimated_median_network_quality_.http_rtt() != | 552 if (estimated_quality_at_last_main_frame_.http_rtt() != |
| 500 nqe::internal::InvalidRTT()) { | 553 nqe::internal::InvalidRTT()) { |
| 501 RecordHttpRTTUMA( | 554 RecordHttpRTTUMA( |
| 502 estimated_median_network_quality_.http_rtt().InMilliseconds(), | 555 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds(), |
| 503 observed_http_rtt.InMilliseconds()); | 556 observed_http_rtt.InMilliseconds()); |
| 504 } | 557 } |
| 505 } | 558 } |
| 506 | 559 |
| 560 void NetworkQualityEstimator::RecordAccuracyAfterMainFrame( | |
| 561 const base::TimeDelta& measuring_duration) const { | |
|
Alexei Svitkine (slow)
2016/06/06 15:11:55
Nit: I think TimeDeltas should be passed by value.
tbansal1
2016/06/07 22:00:10
Done.
| |
| 562 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 563 DCHECK_EQ(0, measuring_duration.InMilliseconds() % 1000); | |
| 564 DCHECK(ContainsValue(GetAccuracyRecordingIntervals(), measuring_duration)); | |
| 565 | |
| 566 const base::TimeTicks now = tick_clock_->NowTicks(); | |
| 567 | |
| 568 // Return if the time since |last_main_frame_request_| is less than | |
| 569 // |measuring_duration|. This may happen if another main frame request started | |
| 570 // during last |measuring_duration|. Returning here ensures that we do not | |
| 571 // take inaccurate readings. | |
| 572 if (now - last_main_frame_request_ < measuring_duration) | |
| 573 return; | |
| 574 | |
| 575 // Return if the time since |last_main_frame_request_| is off by a factor of | |
| 576 // 2. This can happen if the task is executed much later than its scheduled | |
| 577 // time. Returning here ensures that we do not take inaccurate readings. | |
| 578 if (now - last_main_frame_request_ > 2 * measuring_duration) | |
| 579 return; | |
| 580 | |
| 581 base::TimeDelta recent_http_rtt; | |
| 582 if (estimated_quality_at_last_main_frame_.http_rtt() != | |
| 583 nqe::internal::InvalidRTT() && | |
| 584 GetRecentHttpRTTMedian(last_main_frame_request_, &recent_http_rtt)) { | |
| 585 const int estimated_observed_diff_milliseconds = | |
| 586 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds() - | |
| 587 recent_http_rtt.InMilliseconds(); | |
| 588 | |
| 589 const std::string sign_suffix = | |
| 590 estimated_observed_diff_milliseconds >= 0 ? "Positive." : "Negative."; | |
| 591 | |
| 592 base::HistogramBase* histogram = base::Histogram::FactoryGet( | |
| 593 "NQE.Accuracy.HttpRTT.EstimatedObservedDiff." + sign_suffix + | |
| 594 base::IntToString(measuring_duration.InSeconds()) + "." + | |
| 595 GetHistogramSuffixObservedRTT(recent_http_rtt), | |
| 596 1, 10 * 1000 /* 10 seconds */, 50 /* Number of buckets */, | |
| 597 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 598 histogram->Add(std::abs(estimated_observed_diff_milliseconds)); | |
| 599 } | |
| 600 | |
| 601 base::TimeDelta recent_transport_rtt; | |
| 602 if (estimated_quality_at_last_main_frame_.transport_rtt() != | |
| 603 nqe::internal::InvalidRTT() && | |
| 604 GetRecentTransportRTTMedian(last_main_frame_request_, | |
| 605 &recent_transport_rtt)) { | |
| 606 const int estimated_observed_diff_milliseconds = | |
| 607 estimated_quality_at_last_main_frame_.transport_rtt().InMilliseconds() - | |
| 608 recent_transport_rtt.InMilliseconds(); | |
| 609 | |
| 610 const std::string sign_suffix = | |
| 611 estimated_observed_diff_milliseconds >= 0 ? "Positive." : "Negative."; | |
| 612 | |
| 613 base::HistogramBase* histogram = base::Histogram::FactoryGet( | |
| 614 "NQE.Accuracy.TransportRTT.EstimatedObservedDiff." + sign_suffix + | |
| 615 base::IntToString(measuring_duration.InSeconds()) + "." + | |
| 616 GetHistogramSuffixObservedRTT(recent_transport_rtt), | |
| 617 1, 10 * 1000 /* 10 seconds */, 50 /* Number of buckets */, | |
| 618 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 619 histogram->Add(std::abs(estimated_observed_diff_milliseconds)); | |
| 620 } | |
| 621 | |
| 622 // TODO(tbansal): Add histogram for downstream throughput and effective | |
| 623 // connection type. | |
| 624 } | |
| 625 | |
| 507 void NetworkQualityEstimator::NotifyRequestCompleted( | 626 void NetworkQualityEstimator::NotifyRequestCompleted( |
| 508 const URLRequest& request) { | 627 const URLRequest& request) { |
| 509 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 628 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 510 "NetworkQualityEstimator::NotifyRequestCompleted"); | 629 "NetworkQualityEstimator::NotifyRequestCompleted"); |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); | 630 DCHECK(thread_checker_.CalledOnValidThread()); |
| 512 | 631 |
| 513 if (!RequestSchemeIsHTTPOrHTTPS(request)) | 632 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
| 514 return; | 633 return; |
| 515 | 634 |
| 516 throughput_analyzer_->NotifyRequestCompleted(request); | 635 throughput_analyzer_->NotifyRequestCompleted(request); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { | 751 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { |
| 633 RecordExternalEstimateProviderMetrics( | 752 RecordExternalEstimateProviderMetrics( |
| 634 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 753 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 635 external_estimate_provider_->Update(); | 754 external_estimate_provider_->Update(); |
| 636 } | 755 } |
| 637 | 756 |
| 638 // Read any cached estimates for the new network. If cached estimates are | 757 // Read any cached estimates for the new network. If cached estimates are |
| 639 // unavailable, add the default estimates. | 758 // unavailable, add the default estimates. |
| 640 if (!ReadCachedNetworkQualityEstimate()) | 759 if (!ReadCachedNetworkQualityEstimate()) |
| 641 AddDefaultEstimates(); | 760 AddDefaultEstimates(); |
| 642 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); | 761 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); |
| 643 throughput_analyzer_->OnConnectionTypeChanged(); | 762 throughput_analyzer_->OnConnectionTypeChanged(); |
| 644 MaybeRecomputeEffectiveConnectionType(); | 763 MaybeRecomputeEffectiveConnectionType(); |
| 645 } | 764 } |
| 646 | 765 |
| 647 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { | 766 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| 648 DCHECK(thread_checker_.CalledOnValidThread()); | 767 DCHECK(thread_checker_.CalledOnValidThread()); |
| 649 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { | 768 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { |
| 650 base::HistogramBase* rtt_histogram = | 769 base::HistogramBase* rtt_histogram = |
| 651 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); | 770 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 652 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); | 771 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 DCHECK(external_estimate_provider_); | 1121 DCHECK(external_estimate_provider_); |
| 1003 | 1122 |
| 1004 RecordExternalEstimateProviderMetrics( | 1123 RecordExternalEstimateProviderMetrics( |
| 1005 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); | 1124 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); |
| 1006 | 1125 |
| 1007 if (rtt > base::TimeDelta()) { | 1126 if (rtt > base::TimeDelta()) { |
| 1008 RecordExternalEstimateProviderMetrics( | 1127 RecordExternalEstimateProviderMetrics( |
| 1009 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); | 1128 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); |
| 1010 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); | 1129 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); |
| 1011 rtt_observations_.AddObservation( | 1130 rtt_observations_.AddObservation( |
| 1012 RttObservation(rtt, base::TimeTicks::Now(), | 1131 RttObservation(rtt, tick_clock_->NowTicks(), |
| 1013 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1132 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1014 } | 1133 } |
| 1015 | 1134 |
| 1016 if (downstream_throughput_kbps > 0) { | 1135 if (downstream_throughput_kbps > 0) { |
| 1017 RecordExternalEstimateProviderMetrics( | 1136 RecordExternalEstimateProviderMetrics( |
| 1018 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); | 1137 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); |
| 1019 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", | 1138 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", |
| 1020 downstream_throughput_kbps); | 1139 downstream_throughput_kbps); |
| 1021 downstream_throughput_kbps_observations_.AddObservation( | 1140 downstream_throughput_kbps_observations_.AddObservation( |
| 1022 ThroughputObservation( | 1141 ThroughputObservation( |
| 1023 downstream_throughput_kbps, base::TimeTicks::Now(), | 1142 downstream_throughput_kbps, tick_clock_->NowTicks(), |
| 1024 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1143 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1025 } | 1144 } |
| 1026 } | 1145 } |
| 1027 | 1146 |
| 1028 const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( | 1147 const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( |
| 1029 EffectiveConnectionType type) const { | 1148 EffectiveConnectionType type) const { |
| 1030 switch (type) { | 1149 switch (type) { |
| 1031 case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: | 1150 case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: |
| 1032 return "Unknown"; | 1151 return "Unknown"; |
| 1033 case EFFECTIVE_CONNECTION_TYPE_OFFLINE: | 1152 case EFFECTIVE_CONNECTION_TYPE_OFFLINE: |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1190 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1309 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1191 DCHECK(thread_checker_.CalledOnValidThread()); | 1310 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1192 | 1311 |
| 1193 // TODO(tbansal): Add hysteresis in the notification. | 1312 // TODO(tbansal): Add hysteresis in the notification. |
| 1194 FOR_EACH_OBSERVER( | 1313 FOR_EACH_OBSERVER( |
| 1195 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1314 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1196 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1315 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1197 } | 1316 } |
| 1198 | 1317 |
| 1199 } // namespace net | 1318 } // namespace net |
| OLD | NEW |