blob: e95aa2973e513ec9f7a07b4ff602576cc8c6fd4a [file] [log] [blame]
[email protected]5b199522012-12-22 17:24:441// 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.
4
maxbogueea16ff412016-10-28 16:35:295#include "components/sync_preferences/pref_service_syncable.h"
[email protected]5b199522012-12-22 17:24:446
François Degrosee2f030d2017-12-04 00:29:017#include <utility>
8
[email protected]5b199522012-12-22 17:24:449#include "base/bind.h"
sdefresne0b1722f02015-09-14 18:12:1210#include "base/callback.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
[email protected]3ea1b182013-02-08 22:38:4112#include "base/strings/string_number_conversions.h"
[email protected]5b199522012-12-22 17:24:4413#include "base/value_conversions.h"
[email protected]f0c8c4992014-05-15 17:37:2614#include "components/pref_registry/pref_registry_syncable.h"
brettwf00b9b42016-02-01 22:11:3815#include "components/prefs/default_pref_store.h"
Sam McNallyaa67d7f22017-09-04 03:34:0616#include "components/prefs/in_memory_pref_store.h"
brettwf00b9b42016-02-01 22:11:3817#include "components/prefs/overlay_user_pref_store.h"
18#include "components/prefs/pref_notifier_impl.h"
19#include "components/prefs/pref_registry.h"
maxbogueea16ff412016-10-28 16:35:2920#include "components/sync_preferences/pref_model_associator.h"
21#include "components/sync_preferences/pref_service_syncable_observer.h"
Sam McNally538fca1e2017-07-14 03:10:4322#include "services/preferences/public/cpp/in_process_service_factory.h"
Johan Tibell26b550b2017-06-20 04:59:1323#include "services/preferences/public/cpp/persistent_pref_store_client.h"
24#include "services/preferences/public/cpp/pref_registry_serializer.h"
Ken Rockotf7f533e2018-02-11 02:21:3325#include "services/preferences/public/mojom/preferences.mojom.h"
Johan Tibell26b550b2017-06-20 04:59:1326#include "services/service_manager/public/cpp/connector.h"
[email protected]5b199522012-12-22 17:24:4427
maxbogueea16ff412016-10-28 16:35:2928namespace sync_preferences {
sdefresne50c1e522015-09-18 09:47:5129
Tim Schumann13ef1e82018-05-30 01:37:1530// TODO(tschumann): Handing out pointers to this in the constructor is an
31// anti-pattern. Instead, introduce a factory method which first constructs
32// the PrefServiceSyncable instance and then the members which need a reference
33// to the PrefServiceSycnable instance.
[email protected]5b199522012-12-22 17:24:4434PrefServiceSyncable::PrefServiceSyncable(
François Degrosee2f030d2017-12-04 00:29:0135 std::unique_ptr<PrefNotifierImpl> pref_notifier,
36 std::unique_ptr<PrefValueStore> pref_value_store,
François Degrose39cf535e2018-02-07 02:08:3037 scoped_refptr<PersistentPrefStore> user_prefs,
38 scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry,
sdefresne96bc5cc2015-09-15 15:47:5439 const PrefModelAssociatorClient* pref_model_associator_client,
François Degrose39cf535e2018-02-07 02:08:3040 base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>
[email protected]5b199522012-12-22 17:24:4441 read_error_callback,
42 bool async)
François Degrosee2f030d2017-12-04 00:29:0143 : PrefService(std::move(pref_notifier),
44 std::move(pref_value_store),
François Degrose39cf535e2018-02-07 02:08:3045 std::move(user_prefs),
Tim Schumann13ef1e82018-05-30 01:37:1546 pref_registry,
François Degrose39cf535e2018-02-07 02:08:3047 std::move(read_error_callback),
sdefresne96bc5cc2015-09-15 15:47:5448 async),
mharanczyk90466492016-07-20 16:10:2249 pref_service_forked_(false),
Tim Schumann13ef1e82018-05-30 01:37:1550 unknown_pref_accessor_(this, pref_registry.get(), user_pref_store_.get()),
51 pref_sync_associator_(pref_model_associator_client,
52 syncer::PREFERENCES,
53 &unknown_pref_accessor_),
sdefresne96bc5cc2015-09-15 15:47:5454 priority_pref_sync_associator_(pref_model_associator_client,
Tim Schumann13ef1e82018-05-30 01:37:1555 syncer::PRIORITY_PREFERENCES,
56 &unknown_pref_accessor_),
57 pref_registry_(std::move(pref_registry)) {
[email protected]5b199522012-12-22 17:24:4458 pref_sync_associator_.SetPrefService(this);
[email protected]43fe640e2013-03-27 22:18:5559 priority_pref_sync_associator_.SetPrefService(this);
[email protected]c17427552012-12-27 13:11:5560
[email protected]43fe640e2013-03-27 22:18:5561 // Let PrefModelAssociators know about changes to preference values.
François Degrosee2f030d2017-12-04 00:29:0162 pref_value_store_->set_callback(base::Bind(
sdefresne0b1722f02015-09-14 18:12:1263 &PrefServiceSyncable::ProcessPrefChange, base::Unretained(this)));
[email protected]c753f142013-02-10 13:14:0464
65 // Add already-registered syncable preferences to PrefModelAssociator.
François Degrose39cf535e2018-02-07 02:08:3066 for (const auto& entry : *pref_registry_) {
67 const std::string& path = entry.first;
raymes25fb8e7f2015-04-27 01:23:1068 AddRegisteredSyncablePreference(path,
69 pref_registry_->GetRegistrationFlags(path));
[email protected]c753f142013-02-10 13:14:0470 }
71
72 // Watch for syncable preferences registered after this point.
François Degrose39cf535e2018-02-07 02:08:3073 static_cast<user_prefs::PrefRegistrySyncable*>(pref_registry_.get())
74 ->SetSyncableRegistrationCallback(base::BindRepeating(
75 &PrefServiceSyncable::AddRegisteredSyncablePreference,
76 base::Unretained(this)));
[email protected]5b199522012-12-22 17:24:4477}
78
[email protected]c753f142013-02-10 13:14:0479PrefServiceSyncable::~PrefServiceSyncable() {
80 // Remove our callback from the registry, since it may outlive us.
Tim Schumann13ef1e82018-05-30 01:37:1581 pref_registry_->SetSyncableRegistrationCallback(
[email protected]443e9312013-05-06 06:17:3482 user_prefs::PrefRegistrySyncable::SyncableRegistrationCallback());
[email protected]c753f142013-02-10 13:14:0483}
[email protected]5b199522012-12-22 17:24:4484
François Degros9d35fc572018-02-05 22:32:4585std::unique_ptr<PrefServiceSyncable>
86PrefServiceSyncable::CreateIncognitoPrefService(
sdefresne0b1722f02015-09-14 18:12:1287 PrefStore* incognito_extension_pref_store,
Ramin Halavatif623bafe92018-07-17 12:12:5888 const std::vector<const char*>& persistent_pref_names,
Sam McNally538fca1e2017-07-14 03:10:4389 std::unique_ptr<PrefValueStore::Delegate> delegate) {
[email protected]5b199522012-12-22 17:24:4490 pref_service_forked_ = true;
François Degrosee2f030d2017-12-04 00:29:0191 auto pref_notifier = std::make_unique<PrefNotifierImpl>();
[email protected]b1de2c72013-02-06 02:45:4792
[email protected]443e9312013-05-06 06:17:3493 scoped_refptr<user_prefs::PrefRegistrySyncable> forked_registry =
Tim Schumann13ef1e82018-05-30 01:37:1594 pref_registry_->ForkForIncognito();
Johan Tibell26b550b2017-06-20 04:59:1395
Sam McNallyaa67d7f22017-09-04 03:34:0696 auto overlay = base::MakeRefCounted<InMemoryPrefStore>();
Sam McNally538fca1e2017-07-14 03:10:4397 if (delegate) {
Sam McNallyaa67d7f22017-09-04 03:34:0698 delegate->InitIncognitoUserPrefs(overlay, user_pref_store_,
Ramin Halavatif623bafe92018-07-17 12:12:5899 persistent_pref_names);
Sam McNally538fca1e2017-07-14 03:10:43100 delegate->InitPrefRegistry(forked_registry.get());
Johan Tibell26b550b2017-06-20 04:59:13101 }
Sam McNallyaa67d7f22017-09-04 03:34:06102 auto incognito_pref_store = base::MakeRefCounted<OverlayUserPrefStore>(
103 overlay.get(), user_pref_store_.get());
Johan Tibell26b550b2017-06-20 04:59:13104
Ramin Halavatif623bafe92018-07-17 12:12:58105 for (const char* persistent_pref_name : persistent_pref_names)
106 incognito_pref_store->RegisterPersistentPref(persistent_pref_name);
Johan Tibell26b550b2017-06-20 04:59:13107
François Degrosee2f030d2017-12-04 00:29:01108 auto pref_value_store = pref_value_store_->CloneAndSpecialize(
109 nullptr, // managed
110 nullptr, // supervised_user
111 incognito_extension_pref_store,
112 nullptr, // command_line_prefs
113 incognito_pref_store.get(),
114 nullptr, // recommended
115 forked_registry->defaults().get(), pref_notifier.get(),
116 std::move(delegate));
François Degros9d35fc572018-02-05 22:32:45117 return std::make_unique<PrefServiceSyncable>(
François Degrosee2f030d2017-12-04 00:29:01118 std::move(pref_notifier), std::move(pref_value_store),
François Degrose39cf535e2018-02-07 02:08:30119 std::move(incognito_pref_store), std::move(forked_registry),
maxbogueea16ff412016-10-28 16:35:29120 pref_sync_associator_.client(), read_error_callback_, false);
[email protected]5b199522012-12-22 17:24:44121}
122
123bool PrefServiceSyncable::IsSyncing() {
124 return pref_sync_associator_.models_associated();
125}
126
[email protected]43fe640e2013-03-27 22:18:55127bool PrefServiceSyncable::IsPrioritySyncing() {
128 return priority_pref_sync_associator_.models_associated();
129}
130
[email protected]f3ca9092013-05-26 02:25:15131bool PrefServiceSyncable::IsPrefSynced(const std::string& name) const {
132 return pref_sync_associator_.IsPrefSynced(name) ||
133 priority_pref_sync_associator_.IsPrefSynced(name);
134}
135
[email protected]57f62122013-01-14 00:59:24136void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver* observer) {
[email protected]5b199522012-12-22 17:24:44137 observer_list_.AddObserver(observer);
138}
139
[email protected]57f62122013-01-14 00:59:24140void PrefServiceSyncable::RemoveObserver(
141 PrefServiceSyncableObserver* observer) {
[email protected]5b199522012-12-22 17:24:44142 observer_list_.RemoveObserver(observer);
143}
144
[email protected]43fe640e2013-03-27 22:18:55145syncer::SyncableService* PrefServiceSyncable::GetSyncableService(
146 const syncer::ModelType& type) {
147 if (type == syncer::PREFERENCES) {
148 return &pref_sync_associator_;
149 } else if (type == syncer::PRIORITY_PREFERENCES) {
150 return &priority_pref_sync_associator_;
151 } else {
152 NOTREACHED() << "invalid model type: " << type;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24153 return nullptr;
[email protected]43fe640e2013-03-27 22:18:55154 }
[email protected]5b199522012-12-22 17:24:44155}
156
157void PrefServiceSyncable::UpdateCommandLinePrefStore(
158 PrefStore* cmd_line_store) {
159 // If |pref_service_forked_| is true, then this PrefService and the forked
160 // copies will be out of sync.
161 DCHECK(!pref_service_forked_);
162 PrefService::UpdateCommandLinePrefStore(cmd_line_store);
163}
164
sdefresne0b1722f02015-09-14 18:12:12165void PrefServiceSyncable::AddSyncedPrefObserver(const std::string& name,
166 SyncedPrefObserver* observer) {
[email protected]0ebc4032013-08-10 07:07:11167 pref_sync_associator_.AddSyncedPrefObserver(name, observer);
168 priority_pref_sync_associator_.AddSyncedPrefObserver(name, observer);
169}
170
171void PrefServiceSyncable::RemoveSyncedPrefObserver(
172 const std::string& name,
173 SyncedPrefObserver* observer) {
174 pref_sync_associator_.RemoveSyncedPrefObserver(name, observer);
175 priority_pref_sync_associator_.RemoveSyncedPrefObserver(name, observer);
176}
177
lshang2cf5c572016-07-15 01:36:32178void PrefServiceSyncable::RegisterMergeDataFinishedCallback(
179 const base::Closure& callback) {
180 pref_sync_associator_.RegisterMergeDataFinishedCallback(callback);
181}
182
raymes25fb8e7f2015-04-27 01:23:10183void PrefServiceSyncable::AddRegisteredSyncablePreference(
184 const std::string& path,
avi5dd91f82015-12-25 22:30:46185 uint32_t flags) {
[email protected]c753f142013-02-10 13:14:04186 DCHECK(FindPreference(path));
raymes51b41a62015-04-24 02:45:04187 if (flags & user_prefs::PrefRegistrySyncable::SYNCABLE_PREF) {
Tim Schumann13ef1e82018-05-30 01:37:15188 DCHECK(!pref_sync_associator_.models_associated() ||
189 pref_registry_->IsWhitelistedLateRegistrationPref(path));
190 pref_sync_associator_.RegisterPref(path);
sdefresne0b1722f02015-09-14 18:12:12191 } else if (flags & user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) {
Tim Schumann13ef1e82018-05-30 01:37:15192 DCHECK(!priority_pref_sync_associator_.models_associated() ||
193 pref_registry_->IsWhitelistedLateRegistrationPref(path));
194 priority_pref_sync_associator_.RegisterPref(path);
[email protected]43fe640e2013-03-27 22:18:55195 }
[email protected]c753f142013-02-10 13:14:04196}
197
[email protected]5b199522012-12-22 17:24:44198void PrefServiceSyncable::OnIsSyncingChanged() {
ericwilligersff2af332016-10-19 00:16:50199 for (auto& observer : observer_list_)
200 observer.OnIsSyncingChanged();
[email protected]5b199522012-12-22 17:24:44201}
[email protected]43fe640e2013-03-27 22:18:55202
203void PrefServiceSyncable::ProcessPrefChange(const std::string& name) {
204 pref_sync_associator_.ProcessPrefChange(name);
205 priority_pref_sync_associator_.ProcessPrefChange(name);
206}
sdefresne50c1e522015-09-18 09:47:51207
maxbogueea16ff412016-10-28 16:35:29208} // namespace sync_preferences