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
,
86 scoped_ptr
<base::Value
> value
,
88 StoreForKey(key
)->SetValue(key
, value
.Pass(), flags
);
91 void SegregatedPrefStore::RemoveValue(const std::string
& key
, uint32 flags
) {
92 StoreForKey(key
)->RemoveValue(key
, flags
);
95 bool SegregatedPrefStore::GetMutableValue(const std::string
& key
,
96 base::Value
** result
) {
97 return StoreForKey(key
)->GetMutableValue(key
, result
);
100 void SegregatedPrefStore::ReportValueChanged(const std::string
& key
,
102 StoreForKey(key
)->ReportValueChanged(key
, flags
);
105 void SegregatedPrefStore::SetValueSilently(const std::string
& key
,
106 scoped_ptr
<base::Value
> value
,
108 StoreForKey(key
)->SetValueSilently(key
, value
.Pass(), flags
);
111 bool SegregatedPrefStore::ReadOnly() const {
112 return selected_pref_store_
->ReadOnly() ||
113 default_pref_store_
->ReadOnly();
116 PersistentPrefStore::PrefReadError
SegregatedPrefStore::GetReadError() const {
117 PersistentPrefStore::PrefReadError read_error
=
118 default_pref_store_
->GetReadError();
119 if (read_error
== PersistentPrefStore::PREF_READ_ERROR_NONE
) {
120 read_error
= selected_pref_store_
->GetReadError();
121 // Ignore NO_FILE from selected_pref_store_.
122 if (read_error
== PersistentPrefStore::PREF_READ_ERROR_NO_FILE
)
123 read_error
= PersistentPrefStore::PREF_READ_ERROR_NONE
;
128 PersistentPrefStore::PrefReadError
SegregatedPrefStore::ReadPrefs() {
129 // Note: Both of these stores own PrefFilters which makes ReadPrefs
130 // asynchronous. This is okay in this case as only the first call will be
131 // truly asynchronous, the second call will then unblock the migration in
132 // TrackedPreferencesMigrator and complete synchronously.
133 default_pref_store_
->ReadPrefs();
134 PersistentPrefStore::PrefReadError selected_store_read_error
=
135 selected_pref_store_
->ReadPrefs();
136 DCHECK_NE(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE
,
137 selected_store_read_error
);
139 return GetReadError();
142 void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate
* error_delegate
) {
143 read_error_delegate_
.reset(error_delegate
);
144 default_pref_store_
->ReadPrefsAsync(NULL
);
145 selected_pref_store_
->ReadPrefsAsync(NULL
);
148 void SegregatedPrefStore::CommitPendingWrite() {
149 default_pref_store_
->CommitPendingWrite();
150 selected_pref_store_
->CommitPendingWrite();
153 void SegregatedPrefStore::SchedulePendingLossyWrites() {
154 default_pref_store_
->SchedulePendingLossyWrites();
155 selected_pref_store_
->SchedulePendingLossyWrites();
158 SegregatedPrefStore::~SegregatedPrefStore() {
159 default_pref_store_
->RemoveObserver(&aggregating_observer_
);
160 selected_pref_store_
->RemoveObserver(&aggregating_observer_
);
163 PersistentPrefStore
* SegregatedPrefStore::StoreForKey(const std::string
& key
) {
164 return (ContainsKey(selected_preference_names_
, key
)
165 ? selected_pref_store_
166 : default_pref_store_
).get();
169 const PersistentPrefStore
* SegregatedPrefStore::StoreForKey(
170 const std::string
& key
) const {
171 return (ContainsKey(selected_preference_names_
, key
)
172 ? selected_pref_store_
173 : default_pref_store_
).get();