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

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: Minor modifications to comments and code Created 5 years, 7 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 e012a99d72fdcc752cf4e9406f8e61651315598a..eaa55299623f1348593c352d204e0ae2142d9bc6 100644
--- a/net/base/network_quality_estimator.cc
+++ b/net/base/network_quality_estimator.cc
@@ -12,8 +12,45 @@
#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 {
+
+// Maximum size of the cache that holds network quality estimates.
+// Smaller size may reduce the cache hit rate due to frequent evictions.
+// Larger size may affect performance.
+const uint32_t kMaximumNetworkQualityCacheSize = 5;
+
+} // namespace
+
namespace net {
+CachedNetworkQuality::CachedNetworkQuality(
+ NetworkChangeNotifier::ConnectionType connection_type,
+ std::string network_name,
+ int median_kbps,
+ int median_rtt_milliseconds)
+ : connection_type(connection_type),
+ network_name(network_name),
+ median_kbps(median_kbps),
+ median_rtt_milliseconds(median_rtt_milliseconds),
+ last_updated(base::TimeTicks::Now()) {
+ DCHECK_NE(network_name, std::string());
+}
+
+CachedNetworkQuality::~CachedNetworkQuality() {
+}
+
+void CachedNetworkQuality::UpdateNetworkQuality(
+ int updated_median_kbps,
+ int updated_median_rtt_milliseconds) {
+ median_kbps = updated_median_kbps;
+ median_rtt_milliseconds = updated_median_rtt_milliseconds;
+ last_updated = base::TimeTicks::Now();
+}
+
NetworkQualityEstimator::NetworkQualityEstimator()
: NetworkQualityEstimator(false) {
}
@@ -27,7 +64,10 @@ NetworkQualityEstimator::NetworkQualityEstimator(
peak_kbps_since_last_connection_change_(0) {
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_name_ = GetCurrentNetworkName();
}
NetworkQualityEstimator::~NetworkQualityEstimator() {
@@ -109,7 +149,8 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
fastest_RTT_since_last_connection_change_);
break;
default:
- NOTREACHED();
+ NOTREACHED() << "Unexpected connection type = "
+ << current_connection_type_;
break;
}
}
@@ -149,15 +190,23 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
peak_kbps_since_last_connection_change_);
break;
default:
- NOTREACHED();
+ NOTREACHED() << "Unexpected connection type = "
+ << current_connection_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;
+ current_network_name_ = GetCurrentNetworkName();
+
+ // Read any cached estimates for the new network.
+ ReadCachedNetworkQualityEstimate();
}
NetworkQuality NetworkQualityEstimator::GetEstimate() const {
@@ -175,4 +224,104 @@ NetworkQuality NetworkQualityEstimator::GetEstimate() const {
peak_kbps_since_last_connection_change_, 0.1);
}
+std::string NetworkQualityEstimator::GetCurrentNetworkName() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN ||
+ current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_NONE ||
+ current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_BLUETOOTH)
+ return std::string();
+
+ if (current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET) {
+ return "ethernet";
+ }
+
+#if defined(OS_ANDROID)
+ if (current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI)
+ return GetWifiSSID();
+ if (current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_2G ||
+ current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_3G ||
+ current_connection_type_ ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_4G)
+ return android::GetTelephonyNetworkOperator();
+ NOTREACHED() << "Unexpected connection type = " << current_connection_type_;
+#endif // OS_ANDROID
+
+ return std::string();
+}
+
+bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (current_network_name_ == "")
+ return false;
+
+ for (const auto& network_quality : cached_network_quality_) {
+ if (network_quality.connection_type != current_connection_type_ ||
+ network_quality.network_name != current_network_name_)
+ continue;
+
+ // TOOD(tbansal): Populate these values back into the median computing
+ // algorithm.
+ // Add UMA to record how frequently match happens.
+ // int64 median_kbps = network_quality.median_kbps;
+ // int64 median_rtt_msec = network_quality.median_rtt_milliseconds;
+ return true;
+ }
+
+ return false;
+}
+
+void NetworkQualityEstimator::CacheNetworkQualityEstimate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (current_network_name_ == "")
+ return;
+
+ // TODO(tbansal): Following variables should be initialized using the median
+ /// values reported by NetworkQualityEstimator.
+ int median_kbps = 0;
+ int median_rtt_milliseconds = 0;
+
+ // If this network is already in the cache, overwrite that entry.
+ for (auto& network_quality : cached_network_quality_) {
+ if (network_quality.connection_type != current_connection_type_ ||
+ network_quality.network_name != current_network_name_)
+ continue;
+
+ network_quality.UpdateNetworkQuality(median_kbps, median_rtt_milliseconds);
+ return;
+ }
+
+ if (cached_network_quality_.size() < kMaximumNetworkQualityCacheSize) {
+ cached_network_quality_.push_back(
+ CachedNetworkQuality(current_connection_type_, current_network_name_,
+ median_kbps, median_rtt_milliseconds));
+ return;
+ }
+
+ DCHECK_EQ(kMaximumNetworkQualityCacheSize, cached_network_quality_.size());
+
+ // Overwrite the oldest entry.
+ int oldest_entry_index = 0;
+ for (size_t i = 0; i < cached_network_quality_.size(); ++i) {
+ if (cached_network_quality_[i].last_updated <
+ cached_network_quality_[oldest_entry_index].last_updated)
+ oldest_entry_index = i;
+ }
+
+ cached_network_quality_[oldest_entry_index] =
+ CachedNetworkQuality(current_connection_type_, current_network_name_,
+ median_kbps, median_rtt_milliseconds);
+
+ DCHECK_EQ(kMaximumNetworkQualityCacheSize, cached_network_quality_.size());
mmenke 2015/05/28 15:25:02 include base/logging.h for DCHECK and NOTREACHED.
tbansal1 2015/05/29 02:27:23 Done.
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698