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 "base/prefs/overlay_user_pref_store.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/values.h" 9 10 OverlayUserPrefStore::OverlayUserPrefStore( 11 PersistentPrefStore* underlay) 12 : underlay_(underlay) { 13 underlay_->AddObserver(this); 14 } 15 16 bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const { 17 return overlay_.GetValue(key, NULL); 18 } 19 20 void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) { 21 observers_.AddObserver(observer); 22 } 23 24 void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) { 25 observers_.RemoveObserver(observer); 26 } 27 28 size_t OverlayUserPrefStore::NumberOfObservers() const { 29 return observers_.size(); 30 } 31 32 bool OverlayUserPrefStore::IsInitializationComplete() const { 33 return underlay_->IsInitializationComplete(); 34 } 35 36 bool OverlayUserPrefStore::GetValue(const std::string& key, 37 const base::Value** result) const { 38 // If the |key| shall NOT be stored in the overlay store, there must not 39 // be an entry. 40 DCHECK(ShallBeStoredInOverlay(key) || !overlay_.GetValue(key, NULL)); 41 42 if (overlay_.GetValue(key, result)) 43 return true; 44 return underlay_->GetValue(GetUnderlayKey(key), result); 45 } 46 47 bool OverlayUserPrefStore::GetMutableValue(const std::string& key, 48 base::Value** result) { 49 if (!ShallBeStoredInOverlay(key)) 50 return underlay_->GetMutableValue(GetUnderlayKey(key), result); 51 52 if (overlay_.GetValue(key, result)) 53 return true; 54 55 // Try to create copy of underlay if the overlay does not contain a value. 56 base::Value* underlay_value = NULL; 57 if (!underlay_->GetMutableValue(GetUnderlayKey(key), &underlay_value)) 58 return false; 59 60 *result = underlay_value->DeepCopy(); 61 overlay_.SetValue(key, *result); 62 return true; 63 } 64 65 void OverlayUserPrefStore::SetValue(const std::string& key, 66 base::Value* value) { 67 if (!ShallBeStoredInOverlay(key)) { 68 underlay_->SetValue(GetUnderlayKey(key), value); 69 return; 70 } 71 72 if (overlay_.SetValue(key, value)) 73 ReportValueChanged(key); 74 } 75 76 void OverlayUserPrefStore::SetValueSilently(const std::string& key, 77 base::Value* value) { 78 if (!ShallBeStoredInOverlay(key)) { 79 underlay_->SetValueSilently(GetUnderlayKey(key), value); 80 return; 81 } 82 83 overlay_.SetValue(key, value); 84 } 85 86 void OverlayUserPrefStore::RemoveValue(const std::string& key) { 87 if (!ShallBeStoredInOverlay(key)) { 88 underlay_->RemoveValue(GetUnderlayKey(key)); 89 return; 90 } 91 92 if (overlay_.RemoveValue(key)) 93 ReportValueChanged(key); 94 } 95 96 void OverlayUserPrefStore::MarkNeedsEmptyValue(const std::string& key) { 97 if (!ShallBeStoredInOverlay(key)) 98 underlay_->MarkNeedsEmptyValue(key); 99 } 100 101 bool OverlayUserPrefStore::ReadOnly() const { 102 return false; 103 } 104 105 PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const { 106 return PersistentPrefStore::PREF_READ_ERROR_NONE; 107 } 108 109 PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() { 110 // We do not read intentionally. 111 OnInitializationCompleted(true); 112 return PersistentPrefStore::PREF_READ_ERROR_NONE; 113 } 114 115 void OverlayUserPrefStore::ReadPrefsAsync( 116 ReadErrorDelegate* error_delegate_raw) { 117 scoped_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw); 118 // We do not read intentionally. 119 OnInitializationCompleted(true); 120 } 121 122 void OverlayUserPrefStore::CommitPendingWrite() { 123 underlay_->CommitPendingWrite(); 124 // We do not write our content intentionally. 125 } 126 127 void OverlayUserPrefStore::ReportValueChanged(const std::string& key) { 128 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 129 } 130 131 void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) { 132 if (!overlay_.GetValue(GetOverlayKey(key), NULL)) 133 ReportValueChanged(GetOverlayKey(key)); 134 } 135 136 void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) { 137 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 138 OnInitializationCompleted(succeeded)); 139 } 140 141 void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) { 142 RegisterOverlayPref(key, key); 143 } 144 145 void OverlayUserPrefStore::RegisterOverlayPref( 146 const std::string& overlay_key, 147 const std::string& underlay_key) { 148 DCHECK(!overlay_key.empty()) << "Overlay key is empty"; 149 DCHECK(overlay_to_underlay_names_map_.find(overlay_key) == 150 overlay_to_underlay_names_map_.end()) << 151 "Overlay key already registered"; 152 DCHECK(!underlay_key.empty()) << "Underlay key is empty"; 153 DCHECK(underlay_to_overlay_names_map_.find(underlay_key) == 154 underlay_to_overlay_names_map_.end()) << 155 "Underlay key already registered"; 156 overlay_to_underlay_names_map_[overlay_key] = underlay_key; 157 underlay_to_overlay_names_map_[underlay_key] = overlay_key; 158 } 159 160 OverlayUserPrefStore::~OverlayUserPrefStore() { 161 underlay_->RemoveObserver(this); 162 } 163 164 const std::string& OverlayUserPrefStore::GetOverlayKey( 165 const std::string& underlay_key) const { 166 NamesMap::const_iterator i = 167 underlay_to_overlay_names_map_.find(underlay_key); 168 return i != underlay_to_overlay_names_map_.end() ? i->second : underlay_key; 169 } 170 171 const std::string& OverlayUserPrefStore::GetUnderlayKey( 172 const std::string& overlay_key) const { 173 NamesMap::const_iterator i = 174 overlay_to_underlay_names_map_.find(overlay_key); 175 return i != overlay_to_underlay_names_map_.end() ? i->second : overlay_key; 176 } 177 178 bool OverlayUserPrefStore::ShallBeStoredInOverlay( 179 const std::string& key) const { 180 return overlay_to_underlay_names_map_.find(key) != 181 overlay_to_underlay_names_map_.end(); 182 } 183