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 bool OverlayUserPrefStore::HasObservers() const { 29 return observers_.might_have_observers(); 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 bool OverlayUserPrefStore::ReadOnly() const { 97 return false; 98 } 99 100 PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const { 101 return PersistentPrefStore::PREF_READ_ERROR_NONE; 102 } 103 104 PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() { 105 // We do not read intentionally. 106 OnInitializationCompleted(true); 107 return PersistentPrefStore::PREF_READ_ERROR_NONE; 108 } 109 110 void OverlayUserPrefStore::ReadPrefsAsync( 111 ReadErrorDelegate* error_delegate_raw) { 112 scoped_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw); 113 // We do not read intentionally. 114 OnInitializationCompleted(true); 115 } 116 117 void OverlayUserPrefStore::CommitPendingWrite() { 118 underlay_->CommitPendingWrite(); 119 // We do not write our content intentionally. 120 } 121 122 void OverlayUserPrefStore::ReportValueChanged(const std::string& key) { 123 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 124 } 125 126 void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) { 127 if (!overlay_.GetValue(GetOverlayKey(key), NULL)) 128 ReportValueChanged(GetOverlayKey(key)); 129 } 130 131 void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) { 132 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 133 OnInitializationCompleted(succeeded)); 134 } 135 136 void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) { 137 RegisterOverlayPref(key, key); 138 } 139 140 void OverlayUserPrefStore::RegisterOverlayPref( 141 const std::string& overlay_key, 142 const std::string& underlay_key) { 143 DCHECK(!overlay_key.empty()) << "Overlay key is empty"; 144 DCHECK(overlay_to_underlay_names_map_.find(overlay_key) == 145 overlay_to_underlay_names_map_.end()) << 146 "Overlay key already registered"; 147 DCHECK(!underlay_key.empty()) << "Underlay key is empty"; 148 DCHECK(underlay_to_overlay_names_map_.find(underlay_key) == 149 underlay_to_overlay_names_map_.end()) << 150 "Underlay key already registered"; 151 overlay_to_underlay_names_map_[overlay_key] = underlay_key; 152 underlay_to_overlay_names_map_[underlay_key] = overlay_key; 153 } 154 155 OverlayUserPrefStore::~OverlayUserPrefStore() { 156 underlay_->RemoveObserver(this); 157 } 158 159 const std::string& OverlayUserPrefStore::GetOverlayKey( 160 const std::string& underlay_key) const { 161 NamesMap::const_iterator i = 162 underlay_to_overlay_names_map_.find(underlay_key); 163 return i != underlay_to_overlay_names_map_.end() ? i->second : underlay_key; 164 } 165 166 const std::string& OverlayUserPrefStore::GetUnderlayKey( 167 const std::string& overlay_key) const { 168 NamesMap::const_iterator i = 169 overlay_to_underlay_names_map_.find(overlay_key); 170 return i != overlay_to_underlay_names_map_.end() ? i->second : overlay_key; 171 } 172 173 bool OverlayUserPrefStore::ShallBeStoredInOverlay( 174 const std::string& key) const { 175 return overlay_to_underlay_names_map_.find(key) != 176 overlay_to_underlay_names_map_.end(); 177 } 178