Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1123)

Unified Diff: net/base/network_quality_estimator.cc

Issue 1144163008: Add in-memory caching of network quality estimates across network changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed bengr comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/base/network_quality_estimator.cc
diff --git a/net/base/network_quality_estimator.cc b/net/base/network_quality_estimator.cc
index 6415ee6e6d7eb36b47ab4fd568d3537283b27729..e7330de6fadeae8e9a3a9a931d696ef88de1a6ab 100644
--- a/net/base/network_quality_estimator.cc
+++ b/net/base/network_quality_estimator.cc
@@ -4,17 +4,23 @@
#include "net/base/network_quality_estimator.h"
-#include <string>
-
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "build/build_config.h"
#include "net/base/net_util.h"
-#include "net/base/network_quality.h"
+#include "net/base/network_interfaces.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
+#if defined(OS_ANDROID)
+#include "net/android/network_library.h"
+#endif // OS_ANDROID
+
namespace net {
+const uint32_t NetworkQualityEstimator::kMaximumNetworkQualityCacheSize = 10;
+
NetworkQualityEstimator::NetworkQualityEstimator()
: NetworkQualityEstimator(false) {
}
@@ -23,12 +29,16 @@ NetworkQualityEstimator::NetworkQualityEstimator(
bool allow_local_host_requests_for_tests)
: allow_localhost_requests_(allow_local_host_requests_for_tests),
last_connection_change_(base::TimeTicks::Now()),
- current_connection_type_(NetworkChangeNotifier::GetConnectionType()),
bytes_read_since_last_connection_change_(false),
- peak_kbps_since_last_connection_change_(0) {
+ peak_kbps_since_last_connection_change_(0),
+ current_network_id_(NetworkID(NetworkChangeNotifier::GetConnectionType(),
+ std::string())) {
static_assert(kMinRequestDurationMicroseconds > 0,
"Minimum request duration must be > 0");
+ static_assert(kMaximumNetworkQualityCacheSize > 0,
+ "Size of the network quality cache must be > 0");
NetworkChangeNotifier::AddConnectionTypeObserver(this);
+ current_network_id_.id = GetCurrentNetworkName();
}
NetworkQualityEstimator::~NetworkQualityEstimator() {
@@ -77,7 +87,7 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
NetworkChangeNotifier::ConnectionType type) {
DCHECK(thread_checker_.CalledOnValidThread());
if (bytes_read_since_last_connection_change_) {
- switch (current_connection_type_) {
+ switch (current_network_id_.type) {
case NetworkChangeNotifier::CONNECTION_UNKNOWN:
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown",
fastest_RTT_since_last_connection_change_);
@@ -111,13 +121,14 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
fastest_RTT_since_last_connection_change_);
break;
default:
- NOTREACHED();
+ NOTREACHED() << "Unexpected connection type = "
+ << current_network_id_.type;
break;
}
}
if (peak_kbps_since_last_connection_change_) {
- switch (current_connection_type_) {
+ switch (current_network_id_.type) {
case NetworkChangeNotifier::CONNECTION_UNKNOWN:
UMA_HISTOGRAM_COUNTS("NQE.PeakKbps.Unknown",
peak_kbps_since_last_connection_change_);
@@ -151,15 +162,28 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
peak_kbps_since_last_connection_change_);
break;
default:
- NOTREACHED();
+ NOTREACHED() << "Unexpected connection type = "
+ << current_network_id_.type;
break;
}
}
+ // Write the estimates of the previous network to the cache.
+ CacheNetworkQualityEstimate();
+
last_connection_change_ = base::TimeTicks::Now();
bytes_read_since_last_connection_change_ = false;
peak_kbps_since_last_connection_change_ = 0;
- current_connection_type_ = type;
+ fastest_RTT_since_last_connection_change_ = base::TimeDelta();
+ current_network_id_.type = type;
+ current_network_id_.id = GetCurrentNetworkName();
+
+ // Read any cached estimates for the new network.
+ ReadCachedNetworkQualityEstimate();
+}
+
+size_t NetworkQualityEstimator::GetCacheSizeForTests() const {
+ return cached_network_quality_.size();
}
NetworkQuality NetworkQualityEstimator::GetEstimate() const {
@@ -177,4 +201,121 @@ NetworkQuality NetworkQualityEstimator::GetEstimate() const {
peak_kbps_since_last_connection_change_, 0.1);
}
+std::string NetworkQualityEstimator::GetCurrentNetworkName() const {
+ // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class
+ // that overrides this method on the Android platform.
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ switch (current_network_id_.type) {
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN:
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_NONE:
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_BLUETOOTH:
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET:
+ return std::string();
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI:
+#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+ return GetWifiSSID();
+#else
+ return std::string();
+#endif
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_2G:
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_3G:
+ case NetworkChangeNotifier::ConnectionType::CONNECTION_4G:
+#if defined(OS_ANDROID)
+ return android::GetTelephonyNetworkOperator();
+#else
+ return std::string();
+#endif
+ default:
+ NOTREACHED() << "Unexpected connection type = "
+ << current_network_id_.type;
+ return std::string();
+ }
+}
+
+bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ CachedNetworkQualities::iterator it =
+ cached_network_quality_.find(current_network_id_);
+ if (it != cached_network_quality_.end()) {
+ // TOOD(tbansal): Populate these values back into the median computing
+ // algorithm.
+ // Add UMA to record how frequently matches happen.
+ // Ensure that the estimates read are non-zero before populating them into
+ // the median computing algorithm.
+ peak_kbps_since_last_connection_change_ =
+ it->second->GetNetworkQuality().peak_throughput_kbps;
+ fastest_RTT_since_last_connection_change_ =
+ it->second->GetNetworkQuality().fastest_rtt;
+ return true;
+ }
+ return false;
+}
+
+void NetworkQualityEstimator::CacheNetworkQualityEstimate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_LE(cached_network_quality_.size(), kMaximumNetworkQualityCacheSize);
+
+ // TODO(tbansal): The following variables should be initialized using the
+ // median values reported by the NetworkQualityEstimator.
+ int median_kbps = peak_kbps_since_last_connection_change_;
+ base::TimeDelta median_rtt = fastest_RTT_since_last_connection_change_;
+
+ // If this network is already in the cache, overwrite that entry.
+ CachedNetworkQualities::iterator it =
+ cached_network_quality_.find(current_network_id_);
+ if (it != cached_network_quality_.end()) {
+ (it->second)->UpdateNetworkQuality(median_kbps, median_rtt);
+ return;
+ }
+
+ if (cached_network_quality_.size() == kMaximumNetworkQualityCacheSize) {
+ // Remove the oldest entry.
+ CachedNetworkQualities::iterator oldest_entry_iterator =
+ cached_network_quality_.begin();
+
+ for (CachedNetworkQualities::iterator iterator =
+ cached_network_quality_.begin();
+ iterator != cached_network_quality_.end(); ++iterator) {
+ if ((oldest_entry_iterator->second)->last_update_time() >
+ (iterator->second)->last_update_time()) {
+ oldest_entry_iterator = iterator;
+ }
+ }
+ cached_network_quality_.erase(oldest_entry_iterator);
+ }
+
+ DCHECK_LT(cached_network_quality_.size(), kMaximumNetworkQualityCacheSize);
+ cached_network_quality_.insert(
+ std::make_pair(current_network_id_,
+ make_scoped_ptr(new CachedNetworkQuality(
+ NetworkQuality(median_rtt, 0.0, median_kbps, 0.0)))));
+ DCHECK_LE(cached_network_quality_.size(), kMaximumNetworkQualityCacheSize);
+}
+
+NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality(
+ const NetworkQuality& network_quality)
+ : last_update_time_(base::TimeTicks::Now()),
+ network_quality_(network_quality) {
+}
+
+NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() {
+}
+
+void NetworkQualityEstimator::CachedNetworkQuality::UpdateNetworkQuality(
+ uint64_t median_kbps,
+ const base::TimeDelta& median_rtt) {
+ DCHECK_GE(median_kbps, 0U);
+ DCHECK_GE(median_rtt, base::TimeDelta());
+ last_update_time_ = base::TimeTicks::Now();
+
+ network_quality_ = NetworkQuality(median_rtt, 0.0, median_kbps, 0.0);
+}
+
+const NetworkQuality
+NetworkQualityEstimator::CachedNetworkQuality::GetNetworkQuality() const {
+ return network_quality_;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698