Index: net/nqe/network_qualities_prefs_manager.cc |
diff --git a/net/nqe/network_qualities_prefs_manager.cc b/net/nqe/network_qualities_prefs_manager.cc |
index bddfa06e821b20277db45eddc5ca5a590cbb7066..770fb0c14e60d27952ed1cd14578460fa5114deb 100644 |
--- a/net/nqe/network_qualities_prefs_manager.cc |
+++ b/net/nqe/network_qualities_prefs_manager.cc |
@@ -4,25 +4,64 @@ |
#include "net/nqe/network_qualities_prefs_manager.h" |
+#include <string> |
#include <utility> |
#include "base/bind.h" |
#include "base/sequenced_task_runner.h" |
#include "base/threading/thread_checker.h" |
#include "base/threading/thread_task_runner_handle.h" |
-#include "base/values.h" |
-#include "net/nqe/cached_network_quality.h" |
#include "net/nqe/network_quality_estimator.h" |
namespace net { |
+namespace { |
+ |
+// Maximum size of the prefs that hold the qualities of different networks. |
+static const size_t kMaxCacheSize = 3u; |
+ |
+// Parses |value| into a map of NetworkIDs and CachedNetworkQualities, |
+// and returns the map. |
+ParsedPrefs ConvertDictionaryValueToMap(const base::DictionaryValue* value) { |
+ ParsedPrefs read_prefs; |
+ |
+ DCHECK_GE(kMaxCacheSize, value->size()); |
+ |
+ for (base::DictionaryValue::Iterator it(*value); !it.IsAtEnd(); |
+ it.Advance()) { |
+ nqe::internal::NetworkID network_id = |
+ nqe::internal::NetworkID::FromString(it.key()); |
+ |
+ std::string effective_connection_type_string; |
+ bool effective_connection_type_available = |
+ it.value().GetAsString(&effective_connection_type_string); |
+ DCHECK(effective_connection_type_available); |
+ |
+ EffectiveConnectionType effective_connection_type = |
+ EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
+ effective_connection_type_available = GetEffectiveConnectionTypeForName( |
+ effective_connection_type_string, &effective_connection_type); |
+ DCHECK(effective_connection_type_available); |
+ |
+ nqe::internal::CachedNetworkQuality cached_network_quality( |
+ effective_connection_type); |
+ read_prefs[network_id] = cached_network_quality; |
+ } |
+ return read_prefs; |
+} |
+ |
+} // namespace |
+ |
NetworkQualitiesPrefsManager::NetworkQualitiesPrefsManager( |
std::unique_ptr<PrefDelegate> pref_delegate) |
: pref_delegate_(std::move(pref_delegate)), |
pref_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
+ prefs_(pref_delegate_->GetDictionaryValue().CreateDeepCopy()), |
network_quality_estimator_(nullptr), |
+ read_prefs_startup_(ConvertDictionaryValueToMap(prefs_.get())), |
pref_weak_ptr_factory_(this) { |
DCHECK(pref_delegate_); |
+ DCHECK_GE(kMaxCacheSize, prefs_->size()); |
pref_weak_ptr_ = pref_weak_ptr_factory_.GetWeakPtr(); |
} |
@@ -41,6 +80,9 @@ void NetworkQualitiesPrefsManager::InitializeOnNetworkThread( |
network_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
network_quality_estimator_ = network_quality_estimator; |
network_quality_estimator_->AddNetworkQualitiesCacheObserver(this); |
+ |
+ // Notify network quality estimator of the read prefs. |
+ network_quality_estimator_->OnPrefsRead(read_prefs_startup_); |
} |
void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQuality( |
@@ -58,6 +100,7 @@ void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQuality( |
void NetworkQualitiesPrefsManager::ShutdownOnPrefThread() { |
DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); |
+ pref_weak_ptr_factory_.InvalidateWeakPtrs(); |
pref_delegate_.reset(); |
} |
@@ -66,15 +109,45 @@ void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQualityOnPrefThread( |
const nqe::internal::CachedNetworkQuality& cached_network_quality) { |
// The prefs can only be written on the pref thread. |
DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); |
- |
- base::DictionaryValue dictionary_value; |
- dictionary_value.SetString( |
- network_id.ToString(), |
- GetNameForEffectiveConnectionType( |
- cached_network_quality.effective_connection_type())); |
+ DCHECK_GE(kMaxCacheSize, prefs_->size()); |
+ |
+ std::string network_id_string = network_id.ToString(); |
+ |
+ // If the network ID contains a period, then return early since the dictionary |
+ // prefs cannot contain period in the path. |
+ // TODO(tbansal): Investigate a better way of storing network IDs with period |
bengr
2016/10/18 21:47:36
Reference a bug.
tbansal1
2016/10/19 18:34:47
I removed the TODO because I do not think this is
|
+ // in them. |
+ if (network_id_string.find(".") != std::string::npos) |
+ return; |
+ |
+ prefs_->SetString(network_id_string, |
+ GetNameForEffectiveConnectionType( |
+ cached_network_quality.effective_connection_type())); |
+ |
+ if (prefs_->size() > kMaxCacheSize) { |
+ // Delete one value that has key different than |network_id|. |
+ DCHECK_EQ(kMaxCacheSize + 1, prefs_->size()); |
+ for (base::DictionaryValue::Iterator it(*(prefs_.get())); !it.IsAtEnd(); |
+ it.Advance()) { |
+ const nqe::internal::NetworkID it_network_id = |
+ nqe::internal::NetworkID::FromString(it.key()); |
+ if (it_network_id != network_id) { |
+ prefs_->RemovePath(it.key(), nullptr); |
+ break; |
+ } |
+ } |
+ } |
+ DCHECK_GE(kMaxCacheSize, prefs_->size()); |
// Notify the pref delegate so that it updates the prefs on the disk. |
- pref_delegate_->SetDictionaryValue(dictionary_value); |
+ pref_delegate_->SetDictionaryValue(*(prefs_.get())); |
+} |
+ |
+ParsedPrefs NetworkQualitiesPrefsManager::ForceReadPrefsForTesting() const { |
+ DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); |
+ std::unique_ptr<base::DictionaryValue> value( |
+ pref_delegate_->GetDictionaryValue().CreateDeepCopy()); |
+ return ConvertDictionaryValueToMap(value.get()); |
} |
} // namespace net |