1 // Copyright (c) 2012 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 "chrome/browser/invalidation/invalidator_storage.h" 6 7 #include "base/base64.h" 8 #include "base/bind.h" 9 #include "base/callback.h" 10 #include "base/location.h" 11 #include "base/logging.h" 12 #include "base/metrics/histogram.h" 13 #include "base/prefs/pref_service.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/task_runner.h" 16 #include "base/values.h" 17 #include "chrome/common/pref_names.h" 18 #include "components/user_prefs/pref_registry_syncable.h" 19 20 namespace { 21 22 const char kInvalidatorMaxInvalidationVersions[] = 23 "invalidator.max_invalidation_versions"; 24 25 26 bool ValueToUnackedInvalidationStorageMap( 27 const ListValue& value, 28 syncer::UnackedInvalidationsMap* map) { 29 for (size_t i = 0; i != value.GetSize(); ++i) { 30 invalidation::ObjectId invalid_id; 31 syncer::UnackedInvalidationSet storage(invalid_id); 32 const base::DictionaryValue* dict; 33 if (!value.GetDictionary(i, &dict) || !storage.ResetFromValue(*dict)) { 34 DLOG(WARNING) << "Failed to parse ObjectState at position " << i; 35 return false; 36 } 37 map->insert(std::make_pair(storage.object_id(), storage)); 38 } 39 return true; 40 } 41 42 scoped_ptr<base::ListValue> UnackedInvalidationStorageMapToValue( 43 const syncer::UnackedInvalidationsMap& map) { 44 scoped_ptr<base::ListValue> value(new base::ListValue); 45 for (syncer::UnackedInvalidationsMap::const_iterator it = map.begin(); 46 it != map.end(); ++it) { 47 value->Append(it->second.ToValue().release()); 48 } 49 return value.Pass(); 50 } 51 52 } // namespace 53 54 namespace invalidation { 55 56 // static 57 void InvalidatorStorage::RegisterProfilePrefs( 58 user_prefs::PrefRegistrySyncable* registry) { 59 registry->RegisterListPref(prefs::kInvalidatorSavedInvalidations, 60 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 61 registry->RegisterStringPref( 62 prefs::kInvalidatorInvalidationState, 63 std::string(), 64 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 65 registry->RegisterStringPref( 66 prefs::kInvalidatorClientId, 67 std::string(), 68 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 69 70 // This pref is obsolete. We register it so we can clear it. 71 // At some point in the future, it will be safe to remove this. 72 registry->RegisterListPref(kInvalidatorMaxInvalidationVersions, 73 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 74 } 75 76 InvalidatorStorage::InvalidatorStorage(PrefService* pref_service) 77 : pref_service_(pref_service) { 78 DCHECK(pref_service); 79 pref_service_->ClearPref(kInvalidatorMaxInvalidationVersions); 80 } 81 82 InvalidatorStorage::~InvalidatorStorage() { 83 } 84 85 void InvalidatorStorage::SetInvalidatorClientId(const std::string& client_id) { 86 DCHECK(thread_checker_.CalledOnValidThread()); 87 Clear(); // We can't reuse our old invalidation state if the ID changes. 88 pref_service_->SetString(prefs::kInvalidatorClientId, client_id); 89 } 90 91 std::string InvalidatorStorage::GetInvalidatorClientId() const { 92 return pref_service_->GetString(prefs::kInvalidatorClientId); 93 } 94 95 void InvalidatorStorage::SetBootstrapData(const std::string& data) { 96 DCHECK(thread_checker_.CalledOnValidThread()); 97 std::string base64_data; 98 base::Base64Encode(data, &base64_data); 99 pref_service_->SetString(prefs::kInvalidatorInvalidationState, 100 base64_data); 101 } 102 103 std::string InvalidatorStorage::GetBootstrapData() const { 104 std::string base64_data( 105 pref_service_->GetString(prefs::kInvalidatorInvalidationState)); 106 std::string data; 107 base::Base64Decode(base64_data, &data); 108 return data; 109 } 110 111 void InvalidatorStorage::SetSavedInvalidations( 112 const syncer::UnackedInvalidationsMap& map) { 113 scoped_ptr<base::ListValue> value(UnackedInvalidationStorageMapToValue(map)); 114 pref_service_->Set(prefs::kInvalidatorSavedInvalidations, *value.get()); 115 } 116 117 syncer::UnackedInvalidationsMap 118 InvalidatorStorage::GetSavedInvalidations() const { 119 syncer::UnackedInvalidationsMap map; 120 const base::ListValue* value = 121 pref_service_->GetList(prefs::kInvalidatorSavedInvalidations); 122 if (!ValueToUnackedInvalidationStorageMap(*value, &map)) { 123 return syncer::UnackedInvalidationsMap(); 124 } else { 125 return map; 126 } 127 } 128 129 void InvalidatorStorage::Clear() { 130 DCHECK(thread_checker_.CalledOnValidThread()); 131 pref_service_->ClearPref(prefs::kInvalidatorSavedInvalidations); 132 pref_service_->ClearPref(prefs::kInvalidatorClientId); 133 pref_service_->ClearPref(prefs::kInvalidatorInvalidationState); 134 } 135 136 } // namespace invalidation 137