Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/nqe/network_quality_estimator_params.h" | |
| 6 | |
| 7 #include "base/strings/string_number_conversions.h" | |
| 8 #include "base/time/time.h" | |
| 9 | |
| 10 namespace { | |
| 11 | |
| 12 // Default value of the half life (in seconds) for computing time weighted | |
| 13 // percentiles. Every half life, the weight of all observations reduces by | |
| 14 // half. Lowering the half life would reduce the weight of older values faster. | |
| 15 const int kDefaultHalfLifeSeconds = 60; | |
| 16 | |
| 17 // Name of the variation parameter that holds the value of the half life (in | |
| 18 // seconds) of the observations. | |
| 19 const char kHalfLifeSecondsParamName[] = "HalfLifeSeconds"; | |
| 20 | |
| 21 // Suffix of the name of the variation parameter that contains the default RTT | |
| 22 // observation (in milliseconds). Complete name of the variation parameter | |
| 23 // would be |ConnectionType|.|kDefaultRTTMsecObservationSuffix| where | |
| 24 // |ConnectionType| is from |kConnectionTypeNames|. For example, variation | |
| 25 // parameter for Wi-Fi would be "WiFi.DefaultMedianRTTMsec". | |
| 26 const char kDefaultRTTMsecObservationSuffix[] = ".DefaultMedianRTTMsec"; | |
| 27 | |
| 28 // Suffix of the name of the variation parameter that contains the default | |
| 29 // downstream throughput observation (in Kbps). Complete name of the variation | |
| 30 // parameter would be |ConnectionType|.|kDefaultKbpsObservationSuffix| where | |
| 31 // |ConnectionType| is from |kConnectionTypeNames|. For example, variation | |
| 32 // parameter for Wi-Fi would be "WiFi.DefaultMedianKbps". | |
| 33 const char kDefaultKbpsObservationSuffix[] = ".DefaultMedianKbps"; | |
| 34 | |
| 35 // Suffix of the name of the variation parameter that contains the threshold | |
| 36 // HTTP RTTs (in milliseconds) for different effective connection types. | |
| 37 // Complete name of the variation parameter would be | |
| 38 // |EffectiveConnectionType|.|kThresholdURLRTTMsecSuffix|. | |
| 39 const char kThresholdURLRTTMsecSuffix[] = ".ThresholdMedianHttpRTTMsec"; | |
| 40 | |
| 41 // Suffix of the name of the variation parameter that contains the threshold | |
| 42 // transport RTTs (in milliseconds) for different effective connection types. | |
| 43 // Complete name of the variation parameter would be | |
| 44 // |EffectiveConnectionType|.|kThresholdTransportRTTMsecSuffix|. | |
| 45 const char kThresholdTransportRTTMsecSuffix[] = | |
| 46 ".ThresholdMedianTransportRTTMsec"; | |
| 47 | |
| 48 // Suffix of the name of the variation parameter that contains the threshold | |
| 49 // downlink throughput (in kbps) for different effective connection types. | |
| 50 // Complete name of the variation parameter would be | |
| 51 // |EffectiveConnectionType|.|kThresholdKbpsSuffix|. | |
| 52 const char kThresholdKbpsSuffix[] = ".ThresholdMedianKbps"; | |
|
bengr
2016/10/27 16:12:29
Why do these variable names not match the string l
tbansal1
2016/10/28 20:26:04
Removed them since they were used only at one plac
| |
| 53 | |
| 54 // Minimum valid value of the variation parameter that holds RTT (in | |
| 55 // milliseconds) values. | |
| 56 static const int kMinimumRTTVariationParameterMsec = 1; | |
| 57 | |
| 58 // Minimum valid value of the variation parameter that holds throughput (in | |
| 59 // kilobits per second) values. | |
| 60 static const int kMinimumThroughputVariationParameterKbps = 1; | |
| 61 | |
| 62 // Returns the value of |parameter_name| read from |variation_params|. If the | |
| 63 // value is unavailable from |variation_params|, then |default_value| is | |
| 64 // returned. | |
| 65 int64_t GetValueForVariationParam( | |
| 66 const std::map<std::string, std::string>& variation_params, | |
| 67 const std::string& parameter_name, | |
| 68 int64_t default_value) { | |
|
bengr
2016/10/27 16:12:29
#include <stdint.h>
tbansal1
2016/10/28 20:26:04
Done.
| |
| 69 const auto it = variation_params.find(parameter_name); | |
| 70 int64_t variations_value = default_value; | |
| 71 if (it != variation_params.end() && | |
| 72 base::StringToInt64(it->second, &variations_value)) { | |
| 73 return variations_value; | |
| 74 } | |
| 75 return default_value; | |
| 76 } | |
| 77 | |
| 78 // Returns the variation value for |parameter_name|. If the value is | |
| 79 // unavailable, |default_value| is returned. | |
| 80 double GetDoubleValueForVariationParamWithDefaultValue( | |
| 81 const std::map<std::string, std::string>& variation_params, | |
| 82 const std::string& parameter_name, | |
| 83 double default_value) { | |
| 84 const auto it = variation_params.find(parameter_name); | |
| 85 if (it == variation_params.end()) | |
| 86 return default_value; | |
| 87 | |
| 88 double variations_value = default_value; | |
| 89 if (!base::StringToDouble(it->second, &variations_value)) | |
| 90 return default_value; | |
| 91 return variations_value; | |
| 92 } | |
| 93 | |
| 94 // Returns the variation value for |parameter_name|. If the value is | |
| 95 // unavailable, |default_value| is returned. | |
| 96 std::string GetStringValueForVariationParamWithDefaultValue( | |
| 97 const std::map<std::string, std::string>& variation_params, | |
| 98 const std::string& parameter_name, | |
| 99 const std::string& default_value) { | |
| 100 const auto it = variation_params.find(parameter_name); | |
| 101 if (it == variation_params.end()) | |
| 102 return default_value; | |
| 103 return it->second; | |
| 104 } | |
| 105 | |
| 106 } // namespace | |
| 107 | |
| 108 namespace net { | |
| 109 | |
| 110 namespace nqe { | |
| 111 | |
| 112 namespace internal { | |
| 113 | |
| 114 std::string GetEffectiveConnectionTypeAlgorithm( | |
| 115 const std::map<std::string, std::string>& variation_params) { | |
| 116 const auto it = variation_params.find("effective_connection_type_algorithm"); | |
| 117 if (it == variation_params.end()) | |
| 118 return std::string(); | |
| 119 return it->second; | |
| 120 } | |
| 121 | |
| 122 double GetWeightMultiplierPerSecond( | |
| 123 const std::map<std::string, std::string>& variation_params) { | |
| 124 static_assert(kDefaultHalfLifeSeconds > 0, | |
| 125 "Default half life duration must be > 0"); | |
| 126 | |
| 127 int half_life_seconds = kDefaultHalfLifeSeconds; | |
| 128 int32_t variations_value = 0; | |
| 129 auto it = variation_params.find(kHalfLifeSecondsParamName); | |
| 130 if (it != variation_params.end() && | |
| 131 base::StringToInt(it->second, &variations_value) && | |
| 132 variations_value >= 1) { | |
| 133 half_life_seconds = variations_value; | |
| 134 } | |
| 135 DCHECK_GT(half_life_seconds, 0); | |
| 136 return pow(0.5, 1.0 / half_life_seconds); | |
| 137 } | |
| 138 | |
| 139 const char* GetNameForConnectionType( | |
| 140 net::NetworkChangeNotifier::ConnectionType connection_type) { | |
| 141 switch (connection_type) { | |
| 142 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 143 return "Unknown"; | |
| 144 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 145 return "Ethernet"; | |
| 146 case net::NetworkChangeNotifier::CONNECTION_WIFI: | |
| 147 return "WiFi"; | |
| 148 case net::NetworkChangeNotifier::CONNECTION_2G: | |
| 149 return "2G"; | |
| 150 case net::NetworkChangeNotifier::CONNECTION_3G: | |
| 151 return "3G"; | |
| 152 case net::NetworkChangeNotifier::CONNECTION_4G: | |
| 153 return "4G"; | |
| 154 case net::NetworkChangeNotifier::CONNECTION_NONE: | |
| 155 return "None"; | |
| 156 case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 157 return "Bluetooth"; | |
| 158 default: | |
| 159 NOTREACHED(); | |
| 160 break; | |
| 161 } | |
| 162 return ""; | |
| 163 } | |
| 164 | |
| 165 void ObtainDefaultObservations( | |
| 166 const std::map<std::string, std::string>& variation_params, | |
| 167 nqe::internal::NetworkQuality default_observations[]) { | |
| 168 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | |
|
bengr
2016/10/27 16:12:29
i should include CONNECTION_LAST?
tbansal1
2016/10/28 20:26:04
Done.
| |
| 169 NetworkChangeNotifier::ConnectionType type = | |
| 170 static_cast<NetworkChangeNotifier::ConnectionType>(i); | |
| 171 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations[i].http_rtt()); | |
| 172 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 173 default_observations[i].transport_rtt()); | |
| 174 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 175 default_observations[i].downstream_throughput_kbps()); | |
| 176 | |
| 177 base::TimeDelta default_rtt = net::nqe::internal::InvalidRTT(); | |
| 178 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | |
| 179 std::string parameter_name = std::string(GetNameForConnectionType(type)) | |
| 180 .append(kDefaultRTTMsecObservationSuffix); | |
| 181 auto it = variation_params.find(parameter_name); | |
| 182 | |
| 183 if (it != variation_params.end() && | |
| 184 base::StringToInt(it->second, &variations_value) && | |
| 185 variations_value >= kMinimumRTTVariationParameterMsec) { | |
| 186 default_rtt = base::TimeDelta::FromMilliseconds(variations_value); | |
| 187 } | |
| 188 | |
| 189 int32_t downstream_throughput_kbps = net::nqe::internal::kInvalidThroughput; | |
| 190 variations_value = kMinimumThroughputVariationParameterKbps - 1; | |
| 191 parameter_name = std::string(GetNameForConnectionType(type)) | |
| 192 .append(kDefaultKbpsObservationSuffix); | |
| 193 it = variation_params.find(parameter_name); | |
| 194 | |
| 195 if (it != variation_params.end() && | |
| 196 base::StringToInt(it->second, &variations_value) && | |
| 197 variations_value >= kMinimumThroughputVariationParameterKbps) { | |
| 198 downstream_throughput_kbps = variations_value; | |
| 199 } | |
| 200 | |
| 201 default_observations[i] = nqe::internal::NetworkQuality( | |
| 202 default_rtt, default_observations[i].transport_rtt(), | |
| 203 downstream_throughput_kbps); | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 void ObtainEffectiveConnectionTypeModelParams( | |
| 208 const std::map<std::string, std::string>& variation_params, | |
| 209 nqe::internal::NetworkQuality connection_thresholds[]) { | |
| 210 // First set the default thresholds. | |
| 211 nqe::internal::NetworkQuality default_effective_connection_type_thresholds | |
| 212 [EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_LAST]; | |
|
bengr
2016/10/27 16:12:29
Do you need the prefix?
tbansal1
2016/10/28 20:26:04
Done.
| |
| 213 | |
| 214 default_effective_connection_type_thresholds | |
| 215 [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality( | |
| 216 // Set to 2010 milliseconds, which corresponds to the 33rd percentile | |
| 217 // of 2G HTTP RTT observations on Android. | |
| 218 base::TimeDelta::FromMilliseconds(2010), | |
| 219 // Set to 1870 milliseconds, which corresponds to the 33rd percentile | |
| 220 // of 2G transport RTT observations on Android. | |
| 221 base::TimeDelta::FromMilliseconds(1870), | |
| 222 nqe::internal::kInvalidThroughput); | |
| 223 | |
| 224 default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_2G] = | |
| 225 nqe::internal::NetworkQuality( | |
| 226 // Set to 1420 milliseconds, which corresponds to 50th percentile of | |
| 227 // 2G | |
| 228 // HTTP RTT observations on Android. | |
| 229 base::TimeDelta::FromMilliseconds(1420), | |
| 230 // Set to 1280 milliseconds, which corresponds to 50th percentile of | |
| 231 // 2G | |
| 232 // transport RTT observations on Android. | |
| 233 base::TimeDelta::FromMilliseconds(1280), | |
| 234 nqe::internal::kInvalidThroughput); | |
| 235 | |
| 236 default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_3G] = | |
| 237 nqe::internal::NetworkQuality( | |
| 238 // Set to 273 milliseconds, which corresponds to 50th percentile of | |
| 239 // 3G HTTP RTT observations on Android. | |
| 240 base::TimeDelta::FromMilliseconds(273), | |
| 241 // Set to 204 milliseconds, which corresponds to 50th percentile of | |
| 242 // 3G transport RTT observations on Android. | |
| 243 base::TimeDelta::FromMilliseconds(204), | |
| 244 nqe::internal::kInvalidThroughput); | |
| 245 | |
| 246 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | |
| 247 EffectiveConnectionType effective_connection_type = | |
| 248 static_cast<EffectiveConnectionType>(i); | |
| 249 DCHECK_EQ(nqe::internal::InvalidRTT(), connection_thresholds[i].http_rtt()); | |
| 250 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 251 connection_thresholds[i].transport_rtt()); | |
| 252 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 253 connection_thresholds[i].downstream_throughput_kbps()); | |
| 254 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | |
| 255 continue; | |
| 256 | |
| 257 std::string connection_type_name = std::string( | |
| 258 GetNameForEffectiveConnectionType(effective_connection_type)); | |
| 259 | |
| 260 connection_thresholds[i].set_http_rtt( | |
| 261 base::TimeDelta::FromMilliseconds(GetValueForVariationParam( | |
| 262 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, | |
| 263 default_effective_connection_type_thresholds[i] | |
| 264 .http_rtt() | |
| 265 .InMilliseconds()))); | |
| 266 | |
| 267 connection_thresholds[i].set_transport_rtt( | |
| 268 base::TimeDelta::FromMilliseconds(GetValueForVariationParam( | |
| 269 variation_params, | |
| 270 connection_type_name + kThresholdTransportRTTMsecSuffix, | |
| 271 default_effective_connection_type_thresholds[i] | |
| 272 .transport_rtt() | |
| 273 .InMilliseconds()))); | |
| 274 | |
| 275 connection_thresholds[i].set_downstream_throughput_kbps( | |
| 276 GetValueForVariationParam( | |
| 277 variation_params, connection_type_name + kThresholdKbpsSuffix, | |
| 278 default_effective_connection_type_thresholds[i] | |
| 279 .downstream_throughput_kbps())); | |
| 280 DCHECK(i == 0 || | |
| 281 connection_thresholds[i].IsFaster(connection_thresholds[i - 1])); | |
| 282 } | |
| 283 } | |
| 284 | |
| 285 double correlation_uma_logging_probability( | |
| 286 const std::map<std::string, std::string>& variation_params) { | |
| 287 double correlation_uma_logging_probability = | |
| 288 GetDoubleValueForVariationParamWithDefaultValue( | |
| 289 variation_params, "correlation_logging_probability", 0.0); | |
| 290 DCHECK_LE(0.0, correlation_uma_logging_probability); | |
| 291 DCHECK_GE(1.0, correlation_uma_logging_probability); | |
| 292 return correlation_uma_logging_probability; | |
| 293 } | |
| 294 | |
| 295 bool forced_effective_connection_type_set( | |
| 296 const std::map<std::string, std::string>& variation_params) { | |
| 297 return !GetStringValueForVariationParamWithDefaultValue( | |
| 298 variation_params, "force_effective_connection_type", "") | |
| 299 .empty(); | |
| 300 } | |
| 301 | |
| 302 EffectiveConnectionType forced_effective_connection_type( | |
| 303 const std::map<std::string, std::string>& variation_params) { | |
| 304 EffectiveConnectionType forced_effective_connection_type = | |
| 305 EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | |
| 306 std::string forced_value = GetStringValueForVariationParamWithDefaultValue( | |
| 307 variation_params, "force_effective_connection_type", | |
| 308 GetNameForEffectiveConnectionType(EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); | |
| 309 DCHECK(!forced_value.empty()); | |
| 310 bool effective_connection_type_available = GetEffectiveConnectionTypeForName( | |
| 311 forced_value, &forced_effective_connection_type); | |
| 312 DCHECK(effective_connection_type_available); | |
| 313 | |
| 314 // Silence unused variable warning in release builds. | |
| 315 (void)effective_connection_type_available; | |
| 316 | |
| 317 return forced_effective_connection_type; | |
| 318 } | |
| 319 | |
| 320 } // namespace internal | |
| 321 | |
| 322 } // namespace nqe | |
| 323 | |
| 324 } // namespace net | |
| OLD | NEW |