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