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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 disallowed_observation_sources_for_http_( | 286 disallowed_observation_sources_for_http_( |
287 {NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, | 287 {NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, |
288 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, | 288 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, |
289 NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, | 289 NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, |
290 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM}), | 290 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM}), |
291 disallowed_observation_sources_for_transport_( | 291 disallowed_observation_sources_for_transport_( |
292 {NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, | 292 {NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, |
293 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE, | 293 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE, |
294 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, | 294 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, |
295 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM}), | 295 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM}), |
296 suppress_notifications_for_testing_(false), | |
296 weak_ptr_factory_(this) { | 297 weak_ptr_factory_(this) { |
297 // None of the algorithms can have an empty name. | 298 // None of the algorithms can have an empty name. |
298 DCHECK(algorithm_name_to_enum_.end() == | 299 DCHECK(algorithm_name_to_enum_.end() == |
299 algorithm_name_to_enum_.find(std::string())); | 300 algorithm_name_to_enum_.find(std::string())); |
300 | 301 |
301 DCHECK_EQ(algorithm_name_to_enum_.size(), | 302 DCHECK_EQ(algorithm_name_to_enum_.size(), |
302 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: | 303 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: |
303 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); | 304 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); |
304 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: | 305 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: |
305 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, | 306 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, |
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1580 DCHECK(thread_checker_.CalledOnValidThread()); | 1581 DCHECK(thread_checker_.CalledOnValidThread()); |
1581 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value); | 1582 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value); |
1582 DCHECK_GT(NETWORK_QUALITY_OBSERVATION_SOURCE_MAX, observation.source); | 1583 DCHECK_GT(NETWORK_QUALITY_OBSERVATION_SOURCE_MAX, observation.source); |
1583 | 1584 |
1584 UMA_HISTOGRAM_ENUMERATION("NQE.RTT.ObservationSource", observation.source, | 1585 UMA_HISTOGRAM_ENUMERATION("NQE.RTT.ObservationSource", observation.source, |
1585 NETWORK_QUALITY_OBSERVATION_SOURCE_MAX); | 1586 NETWORK_QUALITY_OBSERVATION_SOURCE_MAX); |
1586 | 1587 |
1587 // Maybe recompute the effective connection type since a new RTT observation | 1588 // Maybe recompute the effective connection type since a new RTT observation |
1588 // is available. | 1589 // is available. |
1589 MaybeComputeEffectiveConnectionType(); | 1590 MaybeComputeEffectiveConnectionType(); |
1591 | |
1592 if (suppress_notifications_for_testing_) | |
1593 return; | |
1594 | |
1590 for (auto& observer : rtt_observer_list_) { | 1595 for (auto& observer : rtt_observer_list_) { |
1591 observer.OnRTTObservation(observation.value.InMilliseconds(), | 1596 observer.OnRTTObservation(observation.value.InMilliseconds(), |
1592 observation.timestamp, observation.source); | 1597 observation.timestamp, observation.source); |
1593 } | 1598 } |
1594 } | 1599 } |
1595 | 1600 |
1596 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 1601 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
1597 const ThroughputObservation& observation) { | 1602 const ThroughputObservation& observation) { |
1598 DCHECK(thread_checker_.CalledOnValidThread()); | 1603 DCHECK(thread_checker_.CalledOnValidThread()); |
1599 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value); | 1604 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value); |
1600 DCHECK_GT(NETWORK_QUALITY_OBSERVATION_SOURCE_MAX, observation.source); | 1605 DCHECK_GT(NETWORK_QUALITY_OBSERVATION_SOURCE_MAX, observation.source); |
1601 | 1606 |
1602 UMA_HISTOGRAM_ENUMERATION("NQE.Kbps.ObservationSource", observation.source, | 1607 UMA_HISTOGRAM_ENUMERATION("NQE.Kbps.ObservationSource", observation.source, |
1603 NETWORK_QUALITY_OBSERVATION_SOURCE_MAX); | 1608 NETWORK_QUALITY_OBSERVATION_SOURCE_MAX); |
1604 | 1609 |
1605 // Maybe recompute the effective connection type since a new throughput | 1610 // Maybe recompute the effective connection type since a new throughput |
1606 // observation is available. | 1611 // observation is available. |
1607 MaybeComputeEffectiveConnectionType(); | 1612 MaybeComputeEffectiveConnectionType(); |
1613 | |
1614 if (suppress_notifications_for_testing_) | |
1615 return; | |
1616 | |
1608 for (auto& observer : throughput_observer_list_) { | 1617 for (auto& observer : throughput_observer_list_) { |
bengr
2017/05/12 19:09:54
I'd prefer that you didn't add test support into n
tbansal1
2017/05/12 22:18:17
Done.
| |
1609 observer.OnThroughputObservation(observation.value, observation.timestamp, | 1618 observer.OnThroughputObservation(observation.value, observation.timestamp, |
1610 observation.source); | 1619 observation.source); |
1611 } | 1620 } |
1612 } | 1621 } |
1613 | 1622 |
1614 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( | 1623 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( |
1615 int32_t downstream_kbps) { | 1624 int32_t downstream_kbps) { |
1616 DCHECK(thread_checker_.CalledOnValidThread()); | 1625 DCHECK(thread_checker_.CalledOnValidThread()); |
1617 | 1626 |
1618 if (downstream_kbps == 0) | 1627 if (downstream_kbps == 0) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1661 return; | 1670 return; |
1662 } | 1671 } |
1663 ComputeEffectiveConnectionType(); | 1672 ComputeEffectiveConnectionType(); |
1664 } | 1673 } |
1665 | 1674 |
1666 void NetworkQualityEstimator:: | 1675 void NetworkQualityEstimator:: |
1667 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1676 NotifyObserversOfEffectiveConnectionTypeChanged() { |
1668 DCHECK(thread_checker_.CalledOnValidThread()); | 1677 DCHECK(thread_checker_.CalledOnValidThread()); |
1669 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); | 1678 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); |
1670 | 1679 |
1671 // TODO(tbansal): Add hysteresis in the notification. | |
1672 for (auto& observer : effective_connection_type_observer_list_) | |
1673 observer.OnEffectiveConnectionTypeChanged(effective_connection_type_); | |
1674 | |
1675 // Add the estimates of the current network to the cache store. | 1680 // Add the estimates of the current network to the cache store. |
1676 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { | 1681 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { |
1677 network_quality_store_->Add(current_network_id_, | 1682 network_quality_store_->Add(current_network_id_, |
1678 nqe::internal::CachedNetworkQuality( | 1683 nqe::internal::CachedNetworkQuality( |
1679 tick_clock_->NowTicks(), network_quality_, | 1684 tick_clock_->NowTicks(), network_quality_, |
1680 effective_connection_type_)); | 1685 effective_connection_type_)); |
1681 } | 1686 } |
1687 | |
1688 if (suppress_notifications_for_testing_) | |
1689 return; | |
1690 | |
1691 // TODO(tbansal): Add hysteresis in the notification. | |
bengr
2017/05/12 19:09:55
What kind of hysteresis? Consider making the hyste
tbansal1
2017/05/12 22:18:17
Removed this. We can consider adding hysteresis in
| |
1692 for (auto& observer : effective_connection_type_observer_list_) | |
1693 observer.OnEffectiveConnectionTypeChanged(effective_connection_type_); | |
1682 } | 1694 } |
1683 | 1695 |
1684 void NetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed() const { | 1696 void NetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed() const { |
1685 DCHECK(thread_checker_.CalledOnValidThread()); | 1697 DCHECK(thread_checker_.CalledOnValidThread()); |
1686 | 1698 |
1699 if (suppress_notifications_for_testing_) | |
bengr
2017/05/12 19:09:55
Yeah, this is gross. Virtualize.
tbansal1
2017/05/12 22:18:17
Done.
| |
1700 return; | |
1701 | |
1687 // TODO(tbansal): Add hysteresis in the notification. | 1702 // TODO(tbansal): Add hysteresis in the notification. |
1688 for (auto& observer : rtt_and_throughput_estimates_observer_list_) { | 1703 for (auto& observer : rtt_and_throughput_estimates_observer_list_) { |
1689 observer.OnRTTOrThroughputEstimatesComputed( | 1704 observer.OnRTTOrThroughputEstimatesComputed( |
1690 network_quality_.http_rtt(), network_quality_.transport_rtt(), | 1705 network_quality_.http_rtt(), network_quality_.transport_rtt(), |
1691 network_quality_.downstream_throughput_kbps()); | 1706 network_quality_.downstream_throughput_kbps()); |
1692 } | 1707 } |
1693 } | 1708 } |
1694 | 1709 |
1695 void NetworkQualityEstimator::NotifyEffectiveConnectionTypeObserverIfPresent( | 1710 void NetworkQualityEstimator::NotifyEffectiveConnectionTypeObserverIfPresent( |
1696 EffectiveConnectionTypeObserver* observer) const { | 1711 EffectiveConnectionTypeObserver* observer) const { |
1697 DCHECK(thread_checker_.CalledOnValidThread()); | 1712 DCHECK(thread_checker_.CalledOnValidThread()); |
1698 | 1713 |
1714 if (suppress_notifications_for_testing_) | |
1715 return; | |
1699 if (!effective_connection_type_observer_list_.HasObserver(observer)) | 1716 if (!effective_connection_type_observer_list_.HasObserver(observer)) |
1700 return; | 1717 return; |
1701 if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | 1718 if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) |
1702 return; | 1719 return; |
1703 observer->OnEffectiveConnectionTypeChanged(effective_connection_type_); | 1720 observer->OnEffectiveConnectionTypeChanged(effective_connection_type_); |
1704 } | 1721 } |
1705 | 1722 |
1706 void NetworkQualityEstimator::NotifyRTTAndThroughputEstimatesObserverIfPresent( | 1723 void NetworkQualityEstimator::NotifyRTTAndThroughputEstimatesObserverIfPresent( |
1707 RTTAndThroughputEstimatesObserver* observer) const { | 1724 RTTAndThroughputEstimatesObserver* observer) const { |
1708 DCHECK(thread_checker_.CalledOnValidThread()); | 1725 DCHECK(thread_checker_.CalledOnValidThread()); |
1709 | 1726 |
1727 if (suppress_notifications_for_testing_) | |
1728 return; | |
1710 if (!rtt_and_throughput_estimates_observer_list_.HasObserver(observer)) | 1729 if (!rtt_and_throughput_estimates_observer_list_.HasObserver(observer)) |
1711 return; | 1730 return; |
1712 observer->OnRTTOrThroughputEstimatesComputed( | 1731 observer->OnRTTOrThroughputEstimatesComputed( |
1713 network_quality_.http_rtt(), network_quality_.transport_rtt(), | 1732 network_quality_.http_rtt(), network_quality_.transport_rtt(), |
1714 network_quality_.downstream_throughput_kbps()); | 1733 network_quality_.downstream_throughput_kbps()); |
1715 } | 1734 } |
1716 | 1735 |
1717 void NetworkQualityEstimator::AddNetworkQualitiesCacheObserver( | 1736 void NetworkQualityEstimator::AddNetworkQualitiesCacheObserver( |
1718 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* | 1737 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* |
1719 observer) { | 1738 observer) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1813 case STATISTIC_UNWEIGHTED_AVERAGE: | 1832 case STATISTIC_UNWEIGHTED_AVERAGE: |
1814 return "UnweightedAverage"; | 1833 return "UnweightedAverage"; |
1815 case STATISTIC_LAST: | 1834 case STATISTIC_LAST: |
1816 NOTREACHED(); | 1835 NOTREACHED(); |
1817 return ""; | 1836 return ""; |
1818 } | 1837 } |
1819 NOTREACHED(); | 1838 NOTREACHED(); |
1820 return ""; | 1839 return ""; |
1821 } | 1840 } |
1822 | 1841 |
1842 void NetworkQualityEstimator::SuppressNotificationsForTesting() { | |
1843 DCHECK(thread_checker_.CalledOnValidThread()); | |
1844 suppress_notifications_for_testing_ = true; | |
1845 } | |
1846 | |
1823 base::Optional<base::TimeDelta> | 1847 base::Optional<base::TimeDelta> |
1824 NetworkQualityEstimator::NetworkQualityProvider::GetHttpRTT() const { | 1848 NetworkQualityEstimator::NetworkQualityProvider::GetHttpRTT() const { |
1825 return base::Optional<base::TimeDelta>(); | 1849 return base::Optional<base::TimeDelta>(); |
1826 } | 1850 } |
1827 | 1851 |
1828 base::Optional<base::TimeDelta> | 1852 base::Optional<base::TimeDelta> |
1829 NetworkQualityEstimator::NetworkQualityProvider::GetTransportRTT() const { | 1853 NetworkQualityEstimator::NetworkQualityProvider::GetTransportRTT() const { |
1830 return base::Optional<base::TimeDelta>(); | 1854 return base::Optional<base::TimeDelta>(); |
1831 } | 1855 } |
1832 | 1856 |
1833 base::Optional<int32_t> | 1857 base::Optional<int32_t> |
1834 NetworkQualityEstimator::NetworkQualityProvider::GetDownstreamThroughputKbps() | 1858 NetworkQualityEstimator::NetworkQualityProvider::GetDownstreamThroughputKbps() |
1835 const { | 1859 const { |
1836 return base::Optional<int32_t>(); | 1860 return base::Optional<int32_t>(); |
1837 } | 1861 } |
1838 | 1862 |
1839 } // namespace net | 1863 } // namespace net |
OLD | NEW |