Home | History | Annotate | Download | only in prefs
      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