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 "chrome/browser/prefs/pref_service_syncable.h"
8 #include "base/files/file_path.h"
9 #include "base/prefs/default_pref_store.h"
10 #include "base/prefs/overlay_user_pref_store.h"
11 #include "base/prefs/pref_notifier_impl.h"
12 #include "base/prefs/pref_registry.h"
13 #include "base/prefs/pref_value_store.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/value_conversions.h"
16 #include "chrome/browser/prefs/pref_model_associator.h"
17 #include "chrome/browser/prefs/pref_service_syncable_observer.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
20 #include "components/pref_registry/pref_registry_syncable.h"
23 PrefServiceSyncable
* PrefServiceSyncable::FromProfile(Profile
* profile
) {
24 return static_cast<PrefServiceSyncable
*>(profile
->GetPrefs());
28 PrefServiceSyncable
* PrefServiceSyncable::IncognitoFromProfile(
30 return static_cast<PrefServiceSyncable
*>(profile
->GetOffTheRecordPrefs());
33 PrefServiceSyncable::PrefServiceSyncable(
34 PrefNotifierImpl
* pref_notifier
,
35 PrefValueStore
* pref_value_store
,
36 PersistentPrefStore
* user_prefs
,
37 user_prefs::PrefRegistrySyncable
* pref_registry
,
38 base::Callback
<void(PersistentPrefStore::PrefReadError
)>
41 : PrefService(pref_notifier
,
47 pref_sync_associator_(syncer::PREFERENCES
),
48 priority_pref_sync_associator_(syncer::PRIORITY_PREFERENCES
) {
49 pref_sync_associator_
.SetPrefService(this);
50 priority_pref_sync_associator_
.SetPrefService(this);
52 // Let PrefModelAssociators know about changes to preference values.
53 pref_value_store
->set_callback(
54 base::Bind(&PrefServiceSyncable::ProcessPrefChange
,
55 base::Unretained(this)));
57 // Add already-registered syncable preferences to PrefModelAssociator.
58 for (PrefRegistry::const_iterator it
= pref_registry
->begin();
59 it
!= pref_registry
->end(); ++it
) {
60 const std::string
& path
= it
->first
;
61 AddRegisteredSyncablePreference(path
,
62 pref_registry_
->GetRegistrationFlags(path
));
65 // Watch for syncable preferences registered after this point.
66 pref_registry
->SetSyncableRegistrationCallback(
67 base::Bind(&PrefServiceSyncable::AddRegisteredSyncablePreference
,
68 base::Unretained(this)));
71 PrefServiceSyncable::~PrefServiceSyncable() {
72 // Remove our callback from the registry, since it may outlive us.
73 user_prefs::PrefRegistrySyncable
* registry
=
74 static_cast<user_prefs::PrefRegistrySyncable
*>(pref_registry_
.get());
75 registry
->SetSyncableRegistrationCallback(
76 user_prefs::PrefRegistrySyncable::SyncableRegistrationCallback());
79 PrefServiceSyncable
* PrefServiceSyncable::CreateIncognitoPrefService(
80 PrefStore
* incognito_extension_prefs
) {
81 pref_service_forked_
= true;
82 PrefNotifierImpl
* pref_notifier
= new PrefNotifierImpl();
83 OverlayUserPrefStore
* incognito_pref_store
=
84 new OverlayUserPrefStore(user_pref_store_
.get());
85 PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store
);
87 scoped_refptr
<user_prefs::PrefRegistrySyncable
> forked_registry
=
88 static_cast<user_prefs::PrefRegistrySyncable
*>(
89 pref_registry_
.get())->ForkForIncognito();
90 PrefServiceSyncable
* incognito_service
= new PrefServiceSyncable(
92 pref_value_store_
->CloneAndSpecialize(NULL
, // managed
93 NULL
, // supervised_user
94 incognito_extension_prefs
,
95 NULL
, // command_line_prefs
98 forked_registry
->defaults().get(),
100 incognito_pref_store
,
101 forked_registry
.get(),
102 read_error_callback_
,
104 return incognito_service
;
107 bool PrefServiceSyncable::IsSyncing() {
108 return pref_sync_associator_
.models_associated();
111 bool PrefServiceSyncable::IsPrioritySyncing() {
112 return priority_pref_sync_associator_
.models_associated();
115 bool PrefServiceSyncable::IsPrefSynced(const std::string
& name
) const {
116 return pref_sync_associator_
.IsPrefSynced(name
) ||
117 priority_pref_sync_associator_
.IsPrefSynced(name
);
120 void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver
* observer
) {
121 observer_list_
.AddObserver(observer
);
124 void PrefServiceSyncable::RemoveObserver(
125 PrefServiceSyncableObserver
* observer
) {
126 observer_list_
.RemoveObserver(observer
);
129 syncer::SyncableService
* PrefServiceSyncable::GetSyncableService(
130 const syncer::ModelType
& type
) {
131 if (type
== syncer::PREFERENCES
) {
132 return &pref_sync_associator_
;
133 } else if (type
== syncer::PRIORITY_PREFERENCES
) {
134 return &priority_pref_sync_associator_
;
136 NOTREACHED() << "invalid model type: " << type
;
141 void PrefServiceSyncable::UpdateCommandLinePrefStore(
142 PrefStore
* cmd_line_store
) {
143 // If |pref_service_forked_| is true, then this PrefService and the forked
144 // copies will be out of sync.
145 DCHECK(!pref_service_forked_
);
146 PrefService::UpdateCommandLinePrefStore(cmd_line_store
);
149 void PrefServiceSyncable::AddSyncedPrefObserver(
150 const std::string
& name
,
151 SyncedPrefObserver
* observer
) {
152 pref_sync_associator_
.AddSyncedPrefObserver(name
, observer
);
153 priority_pref_sync_associator_
.AddSyncedPrefObserver(name
, observer
);
156 void PrefServiceSyncable::RemoveSyncedPrefObserver(
157 const std::string
& name
,
158 SyncedPrefObserver
* observer
) {
159 pref_sync_associator_
.RemoveSyncedPrefObserver(name
, observer
);
160 priority_pref_sync_associator_
.RemoveSyncedPrefObserver(name
, observer
);
163 void PrefServiceSyncable::AddRegisteredSyncablePreference(
164 const std::string
& path
,
166 DCHECK(FindPreference(path
));
167 if (flags
& user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
) {
168 pref_sync_associator_
.RegisterPref(path
.c_str());
170 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF
) {
171 priority_pref_sync_associator_
.RegisterPref(path
.c_str());
175 void PrefServiceSyncable::OnIsSyncingChanged() {
176 FOR_EACH_OBSERVER(PrefServiceSyncableObserver
, observer_list_
,
177 OnIsSyncingChanged());
180 void PrefServiceSyncable::ProcessPrefChange(const std::string
& name
) {
181 pref_sync_associator_
.ProcessPrefChange(name
);
182 priority_pref_sync_associator_
.ProcessPrefChange(name
);