Index: net/base/network_quality_estimator.cc |
diff --git a/net/base/network_quality_estimator.cc b/net/base/network_quality_estimator.cc |
index e0a10cfc44ba75d8b21ee95d0a5cb6fa7f4a27bc..24e4b07a04d56b084d89488a248a195749d2fb5d 100644 |
--- a/net/base/network_quality_estimator.cc |
+++ b/net/base/network_quality_estimator.cc |
@@ -376,6 +376,18 @@ void NetworkQualityEstimator::RemoveThroughputObserver( |
throughput_observer_list_.RemoveObserver(throughput_observer); |
} |
+void NetworkQualityEstimator::AddPacketCountObserver( |
+ PacketCountObserver* packet_count_observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ packet_count_observer_list_.AddObserver(packet_count_observer); |
+} |
+ |
+void NetworkQualityEstimator::RemovePacketCountObserver( |
+ PacketCountObserver* packet_count_observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ packet_count_observer_list_.RemoveObserver(packet_count_observer); |
+} |
+ |
void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
int32_t actual_value_msec) const { |
DCHECK(thread_checker_.CalledOnValidThread()); |
@@ -429,6 +441,21 @@ void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( |
EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); |
} |
+bool NetworkQualityEstimator::GetObservationSourceForProtocol( |
+ Protocol protocol, |
+ NetworkQualityEstimator::ObservationSource* observation_source) const { |
+ switch (protocol) { |
+ case PROTOCOL_TCP: |
+ *observation_source = TCP; |
+ return true; |
+ case PROTOCOL_QUIC: |
+ *observation_source = QUIC; |
+ return true; |
+ } |
+ NOTREACHED(); |
+ return false; |
+} |
+ |
void NetworkQualityEstimator::OnConnectionTypeChanged( |
NetworkChangeNotifier::ConnectionType type) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
@@ -900,20 +927,45 @@ void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
const base::TimeDelta& rtt) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- switch (protocol) { |
- case PROTOCOL_TCP: |
- NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); |
- return; |
- case PROTOCOL_QUIC: |
- NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); |
- return; |
- default: |
- NOTREACHED(); |
- } |
+ ObservationSource observation_source; |
+ if (!GetObservationSourceForProtocol(protocol, &observation_source)) |
+ return; |
+ |
+ NotifyObserversOfRTT( |
+ RttObservation(rtt, base::TimeTicks::Now(), observation_source)); |
+} |
+ |
+void NetworkQualityEstimator::OnIncrementalPacketCountAvailable( |
+ Protocol protocol, |
+ size_t packets_missing, |
+ size_t packets_received_in_order, |
+ size_t packets_received_out_of_order) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ ObservationSource observation_source; |
+ if (!GetObservationSourceForProtocol(protocol, &observation_source)) |
+ return; |
+ |
+ // Consider it as a packet loss only if at least 3 packets are received after |
+ // the missing packets. |
+ // TODO(tbansal): Maintain a watcher specific buffer that keeps track of |
+ // missing, and at most last N-1 in-order packets. If N (=3) packets with |
+ // sequence number higher than the sequence number of a missing packet are |
+ // received, then the missing packet should be marked as lost, and removed |
+ // from the watcher specific buffer. If an out-of-order packet is received, |
+ // then the state of the missing packet with lowest sequence number should be |
+ // changed to received. This simple approach does not require going back in |
+ // time, and changing the previously taken observations. |
+ NotifyObserversOfIncrementalPacketCount( |
+ packets_missing, packets_received_in_order, packets_received_out_of_order, |
+ base::TimeTicks::Now(), observation_source); |
} |
void NetworkQualityEstimator::NotifyObserversOfRTT( |
const RttObservation& observation) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); |
+ |
FOR_EACH_OBSERVER( |
RTTObserver, rtt_observer_list_, |
OnRTTObservation(observation.value.InMilliseconds(), |
@@ -922,12 +974,30 @@ void NetworkQualityEstimator::NotifyObserversOfRTT( |
void NetworkQualityEstimator::NotifyObserversOfThroughput( |
const ThroughputObservation& observation) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); |
+ |
FOR_EACH_OBSERVER( |
ThroughputObserver, throughput_observer_list_, |
OnThroughputObservation(observation.value, observation.timestamp, |
observation.source)); |
} |
+void NetworkQualityEstimator::NotifyObserversOfIncrementalPacketCount( |
+ size_t packets_missing, |
+ size_t packets_received_in_order, |
+ size_t packets_received_out_of_order, |
+ const base::TimeTicks& timestamp, |
+ ObservationSource source) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK_NE(EXTERNAL_ESTIMATE, source); |
+ |
+ FOR_EACH_OBSERVER(PacketCountObserver, packet_count_observer_list_, |
+ OnIncrementalPacketCountObservation( |
+ packets_missing, packets_received_in_order, |
+ packets_received_out_of_order, timestamp, source)); |
+} |
+ |
NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
const NetworkQuality& network_quality) |
: last_update_time_(base::TimeTicks::Now()), |