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 "components/user_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) {
18 void SegregatedPrefStore::AggregatingObserver::OnPrefValueChanged(
19 const std::string
& key
) {
20 // There is no need to tell clients about changes if they have not yet been
21 // told about initialization.
22 if (failed_sub_initializations_
+ successful_sub_initializations_
< 2)
25 FOR_EACH_OBSERVER(PrefStore::Observer
, outer_
->observers_
,
26 OnPrefValueChanged(key
));
29 void SegregatedPrefStore::AggregatingObserver::OnInitializationCompleted(
32 ++successful_sub_initializations_
;
34 ++failed_sub_initializations_
;
36 DCHECK_LE(failed_sub_initializations_
+ successful_sub_initializations_
, 2);
38 if (failed_sub_initializations_
+ successful_sub_initializations_
== 2) {
39 if (successful_sub_initializations_
== 2 && outer_
->read_error_delegate_
) {
40 PersistentPrefStore::PrefReadError read_error
= outer_
->GetReadError();
41 if (read_error
!= PersistentPrefStore::PREF_READ_ERROR_NONE
)
42 outer_
->read_error_delegate_
->OnError(read_error
);
46 PrefStore::Observer
, outer_
->observers_
,
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() || default_pref_store_
->ReadOnly();
115 PersistentPrefStore::PrefReadError
SegregatedPrefStore::GetReadError() const {
116 PersistentPrefStore::PrefReadError read_error
=
117 default_pref_store_
->GetReadError();
118 if (read_error
== PersistentPrefStore::PREF_READ_ERROR_NONE
) {
119 read_error
= selected_pref_store_
->GetReadError();
120 // Ignore NO_FILE from selected_pref_store_.
121 if (read_error
== PersistentPrefStore::PREF_READ_ERROR_NO_FILE
)
122 read_error
= PersistentPrefStore::PREF_READ_ERROR_NONE
;
127 PersistentPrefStore::PrefReadError
SegregatedPrefStore::ReadPrefs() {
128 // Note: Both of these stores own PrefFilters which makes ReadPrefs
129 // asynchronous. This is okay in this case as only the first call will be
130 // truly asynchronous, the second call will then unblock the migration in
131 // TrackedPreferencesMigrator and complete synchronously.
132 default_pref_store_
->ReadPrefs();
133 PersistentPrefStore::PrefReadError selected_store_read_error
=
134 selected_pref_store_
->ReadPrefs();
135 DCHECK_NE(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE
,
136 selected_store_read_error
);
138 return GetReadError();
141 void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate
* error_delegate
) {
142 read_error_delegate_
.reset(error_delegate
);
143 default_pref_store_
->ReadPrefsAsync(NULL
);
144 selected_pref_store_
->ReadPrefsAsync(NULL
);
147 void SegregatedPrefStore::CommitPendingWrite() {
148 default_pref_store_
->CommitPendingWrite();
149 selected_pref_store_
->CommitPendingWrite();
152 void SegregatedPrefStore::SchedulePendingLossyWrites() {
153 default_pref_store_
->SchedulePendingLossyWrites();
154 selected_pref_store_
->SchedulePendingLossyWrites();
157 SegregatedPrefStore::~SegregatedPrefStore() {
158 default_pref_store_
->RemoveObserver(&aggregating_observer_
);
159 selected_pref_store_
->RemoveObserver(&aggregating_observer_
);
162 PersistentPrefStore
* SegregatedPrefStore::StoreForKey(const std::string
& key
) {
163 return (ContainsKey(selected_preference_names_
, key
)
164 ? selected_pref_store_
165 : default_pref_store_
).get();
168 const PersistentPrefStore
* SegregatedPrefStore::StoreForKey(
169 const std::string
& key
) const {
170 return (ContainsKey(selected_preference_names_
, key
)
171 ? selected_pref_store_
172 : default_pref_store_
).get();