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 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