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.
5 #include "components/syncable_prefs/pref_service_syncable.h"
8 #include "base/callback.h"
9 #include "base/files/file_path.h"
10 #include "base/prefs/default_pref_store.h"
11 #include "base/prefs/overlay_user_pref_store.h"
12 #include "base/prefs/pref_notifier_impl.h"
13 #include "base/prefs/pref_registry.h"
14 #include "base/prefs/pref_value_store.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/value_conversions.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "components/syncable_prefs/pref_model_associator.h"
19 #include "components/syncable_prefs/pref_service_syncable_observer.h"
21 namespace syncable_prefs
{
23 PrefServiceSyncable::PrefServiceSyncable(
24 PrefNotifierImpl
* pref_notifier
,
25 PrefValueStore
* pref_value_store
,
26 PersistentPrefStore
* user_prefs
,
27 user_prefs::PrefRegistrySyncable
* pref_registry
,
28 const PrefModelAssociatorClient
* pref_model_associator_client
,
29 base::Callback
<void(PersistentPrefStore::PrefReadError
)>
32 : PrefService(pref_notifier
,
38 pref_sync_associator_(pref_model_associator_client
, syncer::PREFERENCES
),
39 priority_pref_sync_associator_(pref_model_associator_client
,
40 syncer::PRIORITY_PREFERENCES
) {
41 pref_sync_associator_
.SetPrefService(this);
42 priority_pref_sync_associator_
.SetPrefService(this);
44 // Let PrefModelAssociators know about changes to preference values.
45 pref_value_store
->set_callback(base::Bind(
46 &PrefServiceSyncable::ProcessPrefChange
, base::Unretained(this)));
48 // Add already-registered syncable preferences to PrefModelAssociator.
49 for (PrefRegistry::const_iterator it
= pref_registry
->begin();
50 it
!= pref_registry
->end(); ++it
) {
51 const std::string
& path
= it
->first
;
52 AddRegisteredSyncablePreference(path
,
53 pref_registry_
->GetRegistrationFlags(path
));
56 // Watch for syncable preferences registered after this point.
57 pref_registry
->SetSyncableRegistrationCallback(
58 base::Bind(&PrefServiceSyncable::AddRegisteredSyncablePreference
,
59 base::Unretained(this)));
62 PrefServiceSyncable::~PrefServiceSyncable() {
63 // Remove our callback from the registry, since it may outlive us.
64 user_prefs::PrefRegistrySyncable
* registry
=
65 static_cast<user_prefs::PrefRegistrySyncable
*>(pref_registry_
.get());
66 registry
->SetSyncableRegistrationCallback(
67 user_prefs::PrefRegistrySyncable::SyncableRegistrationCallback());
70 PrefServiceSyncable
* PrefServiceSyncable::CreateIncognitoPrefService(
71 PrefStore
* incognito_extension_pref_store
,
72 const std::vector
<const char*>& overlay_pref_names
) {
73 pref_service_forked_
= true;
74 PrefNotifierImpl
* pref_notifier
= new PrefNotifierImpl();
75 OverlayUserPrefStore
* incognito_pref_store
=
76 new OverlayUserPrefStore(user_pref_store_
.get());
77 for (const char* overlay_pref_name
: overlay_pref_names
)
78 incognito_pref_store
->RegisterOverlayPref(overlay_pref_name
);
80 scoped_refptr
<user_prefs::PrefRegistrySyncable
> forked_registry
=
81 static_cast<user_prefs::PrefRegistrySyncable
*>(
82 pref_registry_
.get())->ForkForIncognito();
83 PrefServiceSyncable
* incognito_service
= new PrefServiceSyncable(
85 pref_value_store_
->CloneAndSpecialize(NULL
, // managed
86 NULL
, // supervised_user
87 incognito_extension_pref_store
,
88 NULL
, // command_line_prefs
91 forked_registry
->defaults().get(),
94 forked_registry
.get(),
95 pref_sync_associator_
.client(),
98 return incognito_service
;
101 bool PrefServiceSyncable::IsSyncing() {
102 return pref_sync_associator_
.models_associated();
105 bool PrefServiceSyncable::IsPrioritySyncing() {
106 return priority_pref_sync_associator_
.models_associated();
109 bool PrefServiceSyncable::IsPrefSynced(const std::string
& name
) const {
110 return pref_sync_associator_
.IsPrefSynced(name
) ||
111 priority_pref_sync_associator_
.IsPrefSynced(name
);
114 void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver
* observer
) {
115 observer_list_
.AddObserver(observer
);
118 void PrefServiceSyncable::RemoveObserver(
119 PrefServiceSyncableObserver
* observer
) {
120 observer_list_
.RemoveObserver(observer
);
123 syncer::SyncableService
* PrefServiceSyncable::GetSyncableService(
124 const syncer::ModelType
& type
) {
125 if (type
== syncer::PREFERENCES
) {
126 return &pref_sync_associator_
;
127 } else if (type
== syncer::PRIORITY_PREFERENCES
) {
128 return &priority_pref_sync_associator_
;
130 NOTREACHED() << "invalid model type: " << type
;
135 void PrefServiceSyncable::UpdateCommandLinePrefStore(
136 PrefStore
* cmd_line_store
) {
137 // If |pref_service_forked_| is true, then this PrefService and the forked
138 // copies will be out of sync.
139 DCHECK(!pref_service_forked_
);
140 PrefService::UpdateCommandLinePrefStore(cmd_line_store
);
143 void PrefServiceSyncable::AddSyncedPrefObserver(const std::string
& name
,
144 SyncedPrefObserver
* observer
) {
145 pref_sync_associator_
.AddSyncedPrefObserver(name
, observer
);
146 priority_pref_sync_associator_
.AddSyncedPrefObserver(name
, observer
);
149 void PrefServiceSyncable::RemoveSyncedPrefObserver(
150 const std::string
& name
,
151 SyncedPrefObserver
* observer
) {
152 pref_sync_associator_
.RemoveSyncedPrefObserver(name
, observer
);
153 priority_pref_sync_associator_
.RemoveSyncedPrefObserver(name
, observer
);
156 // Set the PrefModelAssociatorClient to use for that object during tests.
157 void PrefServiceSyncable::SetPrefModelAssociatorClientForTesting(
158 const PrefModelAssociatorClient
* pref_model_associator_client
) {
159 pref_sync_associator_
.SetPrefModelAssociatorClientForTesting(
160 pref_model_associator_client
);
161 priority_pref_sync_associator_
.SetPrefModelAssociatorClientForTesting(
162 pref_model_associator_client
);
165 void PrefServiceSyncable::AddRegisteredSyncablePreference(
166 const std::string
& path
,
168 DCHECK(FindPreference(path
));
169 if (flags
& user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
) {
170 pref_sync_associator_
.RegisterPref(path
.c_str());
171 } else if (flags
& user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
) {
172 priority_pref_sync_associator_
.RegisterPref(path
.c_str());
176 void PrefServiceSyncable::OnIsSyncingChanged() {
177 FOR_EACH_OBSERVER(PrefServiceSyncableObserver
, observer_list_
,
178 OnIsSyncingChanged());
181 void PrefServiceSyncable::ProcessPrefChange(const std::string
& name
) {
182 pref_sync_associator_
.ProcessPrefChange(name
);
183 priority_pref_sync_associator_
.ProcessPrefChange(name
);
186 } // namespace syncable_prefs