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.
5 #include "chrome/browser/prefs/tracked/segregated_pref_store.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/values.h"
11 SegregatedPrefStore::AggregatingObserver::AggregatingObserver(
12 SegregatedPrefStore
* outer
)
14 failed_sub_initializations_(0),
15 successful_sub_initializations_(0) {}
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)
25 PrefStore::Observer
, outer_
->observers_
, OnPrefValueChanged(key
));
28 void SegregatedPrefStore::AggregatingObserver::OnInitializationCompleted(
31 ++successful_sub_initializations_
;
33 ++failed_sub_initializations_
;
35 DCHECK_LE(failed_sub_initializations_
+ successful_sub_initializations_
, 2);
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
);
47 OnInitializationCompleted(successful_sub_initializations_
== 2));
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_
);
63 void SegregatedPrefStore::AddObserver(Observer
* observer
) {
64 observers_
.AddObserver(observer
);
67 void SegregatedPrefStore::RemoveObserver(Observer
* observer
) {
68 observers_
.RemoveObserver(observer
);
71 bool SegregatedPrefStore::HasObservers() const {
72 return observers_
.might_have_observers();
75 bool SegregatedPrefStore::IsInitializationComplete() const {
76 return default_pref_store_
->IsInitializationComplete() &&
77 selected_pref_store_
->IsInitializationComplete();
80 bool SegregatedPrefStore::GetValue(const std::string
& key
,
81 const base::Value
** result
) const {
82 return StoreForKey(key
)->GetValue(key
, result
);
85 void SegregatedPrefStore::SetValue(const std::string
& key
, base::Value
* value
) {
86 StoreForKey(key
)->SetValue(key
, value
);
89 void SegregatedPrefStore::RemoveValue(const std::string
& key
) {
90 StoreForKey(key
)->RemoveValue(key
);
93 bool SegregatedPrefStore::GetMutableValue(const std::string
& key
,
94 base::Value
** result
) {
95 return StoreForKey(key
)->GetMutableValue(key
, result
);
98 void SegregatedPrefStore::ReportValueChanged(const std::string
& key
) {
99 StoreForKey(key
)->ReportValueChanged(key
);
102 void SegregatedPrefStore::SetValueSilently(const std::string
& key
,
103 base::Value
* value
) {
104 StoreForKey(key
)->SetValueSilently(key
, value
);
107 bool SegregatedPrefStore::ReadOnly() const {
108 return selected_pref_store_
->ReadOnly() ||
109 default_pref_store_
->ReadOnly();
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
;
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
);
135 return GetReadError();
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
);
144 void SegregatedPrefStore::CommitPendingWrite() {
145 default_pref_store_
->CommitPendingWrite();
146 selected_pref_store_
->CommitPendingWrite();
149 SegregatedPrefStore::~SegregatedPrefStore() {
150 default_pref_store_
->RemoveObserver(&aggregating_observer_
);
151 selected_pref_store_
->RemoveObserver(&aggregating_observer_
);
154 PersistentPrefStore
* SegregatedPrefStore::StoreForKey(const std::string
& key
) {
155 return (ContainsKey(selected_preference_names_
, key
)
156 ? selected_pref_store_
157 : default_pref_store_
).get();
160 const PersistentPrefStore
* SegregatedPrefStore::StoreForKey(
161 const std::string
& key
) const {
162 return (ContainsKey(selected_preference_names_
, key
)
163 ? selected_pref_store_
164 : default_pref_store_
).get();