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