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 10OverlayUserPrefStore::OverlayUserPrefStore( 11 PersistentPrefStore* underlay) 12 : underlay_(underlay) { 13 underlay_->AddObserver(this); 14} 15 16bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const { 17 return overlay_.GetValue(key, NULL); 18} 19 20void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) { 21 observers_.AddObserver(observer); 22} 23 24void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) { 25 observers_.RemoveObserver(observer); 26} 27 28bool OverlayUserPrefStore::HasObservers() const { 29 return observers_.might_have_observers(); 30} 31 32bool OverlayUserPrefStore::IsInitializationComplete() const { 33 return underlay_->IsInitializationComplete(); 34} 35 36bool 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 47bool 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 65void 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 76void 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 86void 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 96bool OverlayUserPrefStore::ReadOnly() const { 97 return false; 98} 99 100PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const { 101 return PersistentPrefStore::PREF_READ_ERROR_NONE; 102} 103 104PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() { 105 // We do not read intentionally. 106 OnInitializationCompleted(true); 107 return PersistentPrefStore::PREF_READ_ERROR_NONE; 108} 109 110void 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 117void OverlayUserPrefStore::CommitPendingWrite() { 118 underlay_->CommitPendingWrite(); 119 // We do not write our content intentionally. 120} 121 122void OverlayUserPrefStore::ReportValueChanged(const std::string& key) { 123 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 124} 125 126void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) { 127 if (!overlay_.GetValue(GetOverlayKey(key), NULL)) 128 ReportValueChanged(GetOverlayKey(key)); 129} 130 131void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) { 132 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 133 OnInitializationCompleted(succeeded)); 134} 135 136void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) { 137 RegisterOverlayPref(key, key); 138} 139 140void 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 155OverlayUserPrefStore::~OverlayUserPrefStore() { 156 underlay_->RemoveObserver(this); 157} 158 159const 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 166const 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 173bool 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