Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / syncable_prefs / pref_service_syncable.cc
blobb538a1d6434f7efd86a75fd505b15994833e82f3
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"
7 #include "base/bind.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)>
30 read_error_callback,
31 bool async)
32 : PrefService(pref_notifier,
33 pref_value_store,
34 user_prefs,
35 pref_registry,
36 read_error_callback,
37 async),
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(
84 pref_notifier,
85 pref_value_store_->CloneAndSpecialize(NULL, // managed
86 NULL, // supervised_user
87 incognito_extension_pref_store,
88 NULL, // command_line_prefs
89 incognito_pref_store,
90 NULL, // recommended
91 forked_registry->defaults().get(),
92 pref_notifier),
93 incognito_pref_store,
94 forked_registry.get(),
95 pref_sync_associator_.client(),
96 read_error_callback_,
97 false);
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_;
129 } else {
130 NOTREACHED() << "invalid model type: " << type;
131 return NULL;
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,
167 uint32 flags) {
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