| 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 |actual_rtt|. The width of the intervals |
| 162 // are in exponentially increasing order. |
| 163 std::string GetHistogramSuffixActualRTT(const base::TimeDelta& actual_rtt) { |
| 164 const float rtt_milliseconds = actual_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 { |
| 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 int estimated_actual_diff_milliseconds = |
| 586 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds() - |
| 587 recent_http_rtt.InMilliseconds(); |
| 588 |
| 589 const std::string prefix = |
| 590 estimated_actual_diff_milliseconds >= 0 |
| 591 ? "NQE.Accuracy.HttpRTT.EstimatedActualDiff." |
| 592 : "NQE.Accuracy.HttpRTT.ActualEstimatedDiff."; |
| 593 |
| 594 base::HistogramBase* histogram = base::Histogram::FactoryGet( |
| 595 prefix + base::IntToString(measuring_duration.InSeconds()) + "." + |
| 596 GetHistogramSuffixActualRTT(recent_http_rtt), |
| 597 1, 10 * 1000 /* 10 seconds */, 50 /* Number of buckets */, |
| 598 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 599 histogram->Add(std::abs(estimated_actual_diff_milliseconds)); |
| 600 } |
| 601 |
| 602 base::TimeDelta recent_transport_rtt; |
| 603 if (estimated_quality_at_last_main_frame_.transport_rtt() != |
| 604 nqe::internal::InvalidRTT() && |
| 605 GetRecentTransportRTTMedian(last_main_frame_request_, |
| 606 &recent_transport_rtt)) { |
| 607 int estimated_actual_diff_milliseconds = |
| 608 estimated_quality_at_last_main_frame_.transport_rtt().InMilliseconds() - |
| 609 recent_transport_rtt.InMilliseconds(); |
| 610 |
| 611 const std::string prefix = |
| 612 estimated_actual_diff_milliseconds >= 0 |
| 613 ? "NQE.Accuracy.TransportRTT.EstimatedActualDiff." |
| 614 : "NQE.Accuracy.TransportRTT.ActualEstimatedDiff."; |
| 615 |
| 616 base::HistogramBase* histogram = base::Histogram::FactoryGet( |
| 617 prefix + base::IntToString(measuring_duration.InSeconds()) + "." + |
| 618 GetHistogramSuffixActualRTT(recent_transport_rtt), |
| 619 1, 10 * 1000 /* 10 seconds */, 50 /* Number of buckets */, |
| 620 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 621 histogram->Add(std::abs(estimated_actual_diff_milliseconds)); |
| 622 } |
| 623 |
| 624 // TODO(tbansal): Add histogram for downstream throughput and effective |
| 625 // connection type. |
| 626 } |
| 627 |
| 507 void NetworkQualityEstimator::NotifyRequestCompleted( | 628 void NetworkQualityEstimator::NotifyRequestCompleted( |
| 508 const URLRequest& request) { | 629 const URLRequest& request) { |
| 509 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 630 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
| 510 "NetworkQualityEstimator::NotifyRequestCompleted"); | 631 "NetworkQualityEstimator::NotifyRequestCompleted"); |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); | 632 DCHECK(thread_checker_.CalledOnValidThread()); |
| 512 | 633 |
| 513 if (!RequestSchemeIsHTTPOrHTTPS(request)) | 634 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
| 514 return; | 635 return; |
| 515 | 636 |
| 516 throughput_analyzer_->NotifyRequestCompleted(request); | 637 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) { | 753 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { |
| 633 RecordExternalEstimateProviderMetrics( | 754 RecordExternalEstimateProviderMetrics( |
| 634 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 755 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 635 external_estimate_provider_->Update(); | 756 external_estimate_provider_->Update(); |
| 636 } | 757 } |
| 637 | 758 |
| 638 // Read any cached estimates for the new network. If cached estimates are | 759 // Read any cached estimates for the new network. If cached estimates are |
| 639 // unavailable, add the default estimates. | 760 // unavailable, add the default estimates. |
| 640 if (!ReadCachedNetworkQualityEstimate()) | 761 if (!ReadCachedNetworkQualityEstimate()) |
| 641 AddDefaultEstimates(); | 762 AddDefaultEstimates(); |
| 642 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); | 763 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); |
| 643 throughput_analyzer_->OnConnectionTypeChanged(); | 764 throughput_analyzer_->OnConnectionTypeChanged(); |
| 644 MaybeRecomputeEffectiveConnectionType(); | 765 MaybeRecomputeEffectiveConnectionType(); |
| 645 } | 766 } |
| 646 | 767 |
| 647 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { | 768 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| 648 DCHECK(thread_checker_.CalledOnValidThread()); | 769 DCHECK(thread_checker_.CalledOnValidThread()); |
| 649 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { | 770 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { |
| 650 base::HistogramBase* rtt_histogram = | 771 base::HistogramBase* rtt_histogram = |
| 651 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); | 772 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 652 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); | 773 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_); | 1123 DCHECK(external_estimate_provider_); |
| 1003 | 1124 |
| 1004 RecordExternalEstimateProviderMetrics( | 1125 RecordExternalEstimateProviderMetrics( |
| 1005 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); | 1126 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); |
| 1006 | 1127 |
| 1007 if (rtt > base::TimeDelta()) { | 1128 if (rtt > base::TimeDelta()) { |
| 1008 RecordExternalEstimateProviderMetrics( | 1129 RecordExternalEstimateProviderMetrics( |
| 1009 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); | 1130 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); |
| 1010 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); | 1131 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); |
| 1011 rtt_observations_.AddObservation( | 1132 rtt_observations_.AddObservation( |
| 1012 RttObservation(rtt, base::TimeTicks::Now(), | 1133 RttObservation(rtt, tick_clock_->NowTicks(), |
| 1013 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1134 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1014 } | 1135 } |
| 1015 | 1136 |
| 1016 if (downstream_throughput_kbps > 0) { | 1137 if (downstream_throughput_kbps > 0) { |
| 1017 RecordExternalEstimateProviderMetrics( | 1138 RecordExternalEstimateProviderMetrics( |
| 1018 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); | 1139 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); |
| 1019 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", | 1140 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", |
| 1020 downstream_throughput_kbps); | 1141 downstream_throughput_kbps); |
| 1021 downstream_throughput_kbps_observations_.AddObservation( | 1142 downstream_throughput_kbps_observations_.AddObservation( |
| 1022 ThroughputObservation( | 1143 ThroughputObservation( |
| 1023 downstream_throughput_kbps, base::TimeTicks::Now(), | 1144 downstream_throughput_kbps, tick_clock_->NowTicks(), |
| 1024 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1145 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1025 } | 1146 } |
| 1026 } | 1147 } |
| 1027 | 1148 |
| 1028 const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( | 1149 const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( |
| 1029 EffectiveConnectionType type) const { | 1150 EffectiveConnectionType type) const { |
| 1030 switch (type) { | 1151 switch (type) { |
| 1031 case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: | 1152 case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: |
| 1032 return "Unknown"; | 1153 return "Unknown"; |
| 1033 case EFFECTIVE_CONNECTION_TYPE_OFFLINE: | 1154 case EFFECTIVE_CONNECTION_TYPE_OFFLINE: |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1311 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1191 DCHECK(thread_checker_.CalledOnValidThread()); | 1312 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1192 | 1313 |
| 1193 // TODO(tbansal): Add hysteresis in the notification. | 1314 // TODO(tbansal): Add hysteresis in the notification. |
| 1194 FOR_EACH_OBSERVER( | 1315 FOR_EACH_OBSERVER( |
| 1195 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1316 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1196 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1317 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1197 } | 1318 } |
| 1198 | 1319 |
| 1199 } // namespace net | 1320 } // namespace net |
| OLD | NEW |