Home | History | Annotate | Download | only in tracked
      1 // Copyright 2014 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 "chrome/browser/prefs/tracked/segregated_pref_store.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/stl_util.h"
      9 #include "base/values.h"
     10 
     11 SegregatedPrefStore::AggregatingObserver::AggregatingObserver(
     12     SegregatedPrefStore* outer)
     13     : outer_(outer),
     14       failed_sub_initializations_(0),
     15       successful_sub_initializations_(0) {}
     16 
     17 void SegregatedPrefStore::AggregatingObserver::OnPrefValueChanged(
     18     const std::string& key) {
     19   // There is no need to tell clients about changes if they have not yet been
     20   // told about initialization.
     21   if (failed_sub_initializations_ + successful_sub_initializations_ < 2)
     22     return;
     23 
     24   FOR_EACH_OBSERVER(
     25       PrefStore::Observer, outer_->observers_, OnPrefValueChanged(key));
     26 }
     27 
     28 void SegregatedPrefStore::AggregatingObserver::OnInitializationCompleted(
     29     bool succeeded) {
     30   if (succeeded)
     31     ++successful_sub_initializations_;
     32   else
     33     ++failed_sub_initializations_;
     34 
     35   DCHECK_LE(failed_sub_initializations_ + successful_sub_initializations_, 2);
     36 
     37   if (failed_sub_initializations_ + successful_sub_initializations_ == 2) {
     38     if (successful_sub_initializations_ == 2 && outer_->read_error_delegate_) {
     39       PersistentPrefStore::PrefReadError read_error = outer_->GetReadError();
     40       if (read_error != PersistentPrefStore::PREF_READ_ERROR_NONE)
     41         outer_->read_error_delegate_->OnError(read_error);
     42     }
     43 
     44     FOR_EACH_OBSERVER(
     45         PrefStore::Observer,
     46         outer_->observers_,
     47         OnInitializationCompleted(successful_sub_initializations_ == 2));
     48   }
     49 }
     50 
     51 SegregatedPrefStore::SegregatedPrefStore(
     52     const scoped_refptr<PersistentPrefStore>& default_pref_store,
     53     const scoped_refptr<PersistentPrefStore>& selected_pref_store,
     54     const std::set<std::string>& selected_pref_names)
     55     : default_pref_store_(default_pref_store),
     56       selected_pref_store_(selected_pref_store),
     57       selected_preference_names_(selected_pref_names),
     58       aggregating_observer_(this) {
     59   default_pref_store_->AddObserver(&aggregating_observer_);
     60   selected_pref_store_->AddObserver(&aggregating_observer_);
     61 }
     62 
     63 void SegregatedPrefStore::AddObserver(Observer* observer) {
     64   observers_.AddObserver(observer);
     65 }
     66 
     67 void SegregatedPrefStore::RemoveObserver(Observer* observer) {
     68   observers_.RemoveObserver(observer);
     69 }
     70 
     71 bool SegregatedPrefStore::HasObservers() const {
     72   return observers_.might_have_observers();
     73 }
     74 
     75 bool SegregatedPrefStore::IsInitializationComplete() const {
     76   return default_pref_store_->IsInitializationComplete() &&
     77          selected_pref_store_->IsInitializationComplete();
     78 }
     79 
     80 bool SegregatedPrefStore::GetValue(const std::string& key,
     81                                    const base::Value** result) const {
     82   return StoreForKey(key)->GetValue(key, result);
     83 }
     84 
     85 void SegregatedPrefStore::SetValue(const std::string& key, base::Value* value) {
     86   StoreForKey(key)->SetValue(key, value);
     87 }
     88 
     89 void SegregatedPrefStore::RemoveValue(const std::string& key) {
     90   StoreForKey(key)->RemoveValue(key);
     91 }
     92 
     93 bool SegregatedPrefStore::GetMutableValue(const std::string& key,
     94                                           base::Value** result) {
     95   return StoreForKey(key)->GetMutableValue(key, result);
     96 }
     97 
     98 void SegregatedPrefStore::ReportValueChanged(const std::string& key) {
     99   StoreForKey(key)->ReportValueChanged(key);
    100 }
    101 
    102 void SegregatedPrefStore::SetValueSilently(const std::string& key,
    103                                            base::Value* value) {
    104   StoreForKey(key)->SetValueSilently(key, value);
    105 }
    106 
    107 bool SegregatedPrefStore::ReadOnly() const {
    108   return selected_pref_store_->ReadOnly() ||
    109          default_pref_store_->ReadOnly();
    110 }
    111 
    112 PersistentPrefStore::PrefReadError SegregatedPrefStore::GetReadError() const {
    113   PersistentPrefStore::PrefReadError read_error =
    114       default_pref_store_->GetReadError();
    115   if (read_error == PersistentPrefStore::PREF_READ_ERROR_NONE) {
    116     read_error = selected_pref_store_->GetReadError();
    117     // Ignore NO_FILE from selected_pref_store_.
    118     if (read_error == PersistentPrefStore::PREF_READ_ERROR_NO_FILE)
    119       read_error = PersistentPrefStore::PREF_READ_ERROR_NONE;
    120   }
    121   return read_error;
    122 }
    123 
    124 PersistentPrefStore::PrefReadError SegregatedPrefStore::ReadPrefs() {
    125   // Note: Both of these stores own PrefFilters which makes ReadPrefs
    126   // asynchronous. This is okay in this case as only the first call will be
    127   // truly asynchronous, the second call will then unblock the migration in
    128   // TrackedPreferencesMigrator and complete synchronously.
    129   default_pref_store_->ReadPrefs();
    130   PersistentPrefStore::PrefReadError selected_store_read_error =
    131       selected_pref_store_->ReadPrefs();
    132   DCHECK_NE(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
    133             selected_store_read_error);
    134 
    135   return GetReadError();
    136 }
    137 
    138 void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
    139   read_error_delegate_.reset(error_delegate);
    140   default_pref_store_->ReadPrefsAsync(NULL);
    141   selected_pref_store_->ReadPrefsAsync(NULL);
    142 }
    143 
    144 void SegregatedPrefStore::CommitPendingWrite() {
    145   default_pref_store_->CommitPendingWrite();
    146   selected_pref_store_->CommitPendingWrite();
    147 }
    148 
    149 SegregatedPrefStore::~SegregatedPrefStore() {
    150   default_pref_store_->RemoveObserver(&aggregating_observer_);
    151   selected_pref_store_->RemoveObserver(&aggregating_observer_);
    152 }
    153 
    154 PersistentPrefStore* SegregatedPrefStore::StoreForKey(const std::string& key) {
    155   return ContainsKey(selected_preference_names_, key) ? selected_pref_store_
    156                                                       : default_pref_store_;
    157 }
    158 
    159 const PersistentPrefStore* SegregatedPrefStore::StoreForKey(
    160     const std::string& key) const {
    161   return ContainsKey(selected_preference_names_, key) ? selected_pref_store_
    162                                                       : default_pref_store_;
    163 }
    164