[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 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. |
| 4 | |
maxbogue | ea16ff41 | 2016-10-28 16:35:29 | [diff] [blame] | 5 | #include "components/sync_preferences/pref_service_syncable.h" |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 6 | |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 9 | #include "base/bind.h" |
sdefresne | 0b1722f0 | 2015-09-14 18:12:12 | [diff] [blame] | 10 | #include "base/callback.h" |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 11 | #include "base/files/file_path.h" |
[email protected] | 3ea1b18 | 2013-02-08 22:38:41 | [diff] [blame] | 12 | #include "base/strings/string_number_conversions.h" |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 13 | #include "base/value_conversions.h" |
[email protected] | f0c8c499 | 2014-05-15 17:37:26 | [diff] [blame] | 14 | #include "components/pref_registry/pref_registry_syncable.h" |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 15 | #include "components/prefs/default_pref_store.h" |
Sam McNally | aa67d7f2 | 2017-09-04 03:34:06 | [diff] [blame] | 16 | #include "components/prefs/in_memory_pref_store.h" |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 17 | #include "components/prefs/overlay_user_pref_store.h" |
| 18 | #include "components/prefs/pref_notifier_impl.h" |
| 19 | #include "components/prefs/pref_registry.h" |
maxbogue | ea16ff41 | 2016-10-28 16:35:29 | [diff] [blame] | 20 | #include "components/sync_preferences/pref_model_associator.h" |
| 21 | #include "components/sync_preferences/pref_service_syncable_observer.h" |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 22 | #include "services/preferences/public/cpp/in_process_service_factory.h" |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 23 | #include "services/preferences/public/cpp/persistent_pref_store_client.h" |
| 24 | #include "services/preferences/public/cpp/pref_registry_serializer.h" |
Ken Rockot | f7f533e | 2018-02-11 02:21:33 | [diff] [blame] | 25 | #include "services/preferences/public/mojom/preferences.mojom.h" |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 26 | #include "services/service_manager/public/cpp/connector.h" |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 27 | |
maxbogue | ea16ff41 | 2016-10-28 16:35:29 | [diff] [blame] | 28 | namespace sync_preferences { |
sdefresne | 50c1e52 | 2015-09-18 09:47:51 | [diff] [blame] | 29 | |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 30 | // 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] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 34 | PrefServiceSyncable::PrefServiceSyncable( |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 35 | std::unique_ptr<PrefNotifierImpl> pref_notifier, |
| 36 | std::unique_ptr<PrefValueStore> pref_value_store, |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 37 | scoped_refptr<PersistentPrefStore> user_prefs, |
| 38 | scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry, |
sdefresne | 96bc5cc | 2015-09-15 15:47:54 | [diff] [blame] | 39 | const PrefModelAssociatorClient* pref_model_associator_client, |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 40 | base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 41 | read_error_callback, |
| 42 | bool async) |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 43 | : PrefService(std::move(pref_notifier), |
| 44 | std::move(pref_value_store), |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 45 | std::move(user_prefs), |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 46 | pref_registry, |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 47 | std::move(read_error_callback), |
sdefresne | 96bc5cc | 2015-09-15 15:47:54 | [diff] [blame] | 48 | async), |
mharanczyk | 9046649 | 2016-07-20 16:10:22 | [diff] [blame] | 49 | pref_service_forked_(false), |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 50 | 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_), |
sdefresne | 96bc5cc | 2015-09-15 15:47:54 | [diff] [blame] | 54 | priority_pref_sync_associator_(pref_model_associator_client, |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 55 | syncer::PRIORITY_PREFERENCES, |
| 56 | &unknown_pref_accessor_), |
| 57 | pref_registry_(std::move(pref_registry)) { |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 58 | pref_sync_associator_.SetPrefService(this); |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 59 | priority_pref_sync_associator_.SetPrefService(this); |
[email protected] | c1742755 | 2012-12-27 13:11:55 | [diff] [blame] | 60 | |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 61 | // Let PrefModelAssociators know about changes to preference values. |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 62 | pref_value_store_->set_callback(base::Bind( |
sdefresne | 0b1722f0 | 2015-09-14 18:12:12 | [diff] [blame] | 63 | &PrefServiceSyncable::ProcessPrefChange, base::Unretained(this))); |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 64 | |
| 65 | // Add already-registered syncable preferences to PrefModelAssociator. |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 66 | for (const auto& entry : *pref_registry_) { |
| 67 | const std::string& path = entry.first; |
raymes | 25fb8e7f | 2015-04-27 01:23:10 | [diff] [blame] | 68 | AddRegisteredSyncablePreference(path, |
| 69 | pref_registry_->GetRegistrationFlags(path)); |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | // Watch for syncable preferences registered after this point. |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 73 | static_cast<user_prefs::PrefRegistrySyncable*>(pref_registry_.get()) |
| 74 | ->SetSyncableRegistrationCallback(base::BindRepeating( |
| 75 | &PrefServiceSyncable::AddRegisteredSyncablePreference, |
| 76 | base::Unretained(this))); |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 77 | } |
| 78 | |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 79 | PrefServiceSyncable::~PrefServiceSyncable() { |
| 80 | // Remove our callback from the registry, since it may outlive us. |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 81 | pref_registry_->SetSyncableRegistrationCallback( |
[email protected] | 443e931 | 2013-05-06 06:17:34 | [diff] [blame] | 82 | user_prefs::PrefRegistrySyncable::SyncableRegistrationCallback()); |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 83 | } |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 84 | |
François Degros | 9d35fc57 | 2018-02-05 22:32:45 | [diff] [blame] | 85 | std::unique_ptr<PrefServiceSyncable> |
| 86 | PrefServiceSyncable::CreateIncognitoPrefService( |
sdefresne | 0b1722f0 | 2015-09-14 18:12:12 | [diff] [blame] | 87 | PrefStore* incognito_extension_pref_store, |
Ramin Halavati | f623bafe9 | 2018-07-17 12:12:58 | [diff] [blame] | 88 | const std::vector<const char*>& persistent_pref_names, |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 89 | std::unique_ptr<PrefValueStore::Delegate> delegate) { |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 90 | pref_service_forked_ = true; |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 91 | auto pref_notifier = std::make_unique<PrefNotifierImpl>(); |
[email protected] | b1de2c7 | 2013-02-06 02:45:47 | [diff] [blame] | 92 | |
[email protected] | 443e931 | 2013-05-06 06:17:34 | [diff] [blame] | 93 | scoped_refptr<user_prefs::PrefRegistrySyncable> forked_registry = |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 94 | pref_registry_->ForkForIncognito(); |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 95 | |
Sam McNally | aa67d7f2 | 2017-09-04 03:34:06 | [diff] [blame] | 96 | auto overlay = base::MakeRefCounted<InMemoryPrefStore>(); |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 97 | if (delegate) { |
Sam McNally | aa67d7f2 | 2017-09-04 03:34:06 | [diff] [blame] | 98 | delegate->InitIncognitoUserPrefs(overlay, user_pref_store_, |
Ramin Halavati | f623bafe9 | 2018-07-17 12:12:58 | [diff] [blame] | 99 | persistent_pref_names); |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 100 | delegate->InitPrefRegistry(forked_registry.get()); |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 101 | } |
Sam McNally | aa67d7f2 | 2017-09-04 03:34:06 | [diff] [blame] | 102 | auto incognito_pref_store = base::MakeRefCounted<OverlayUserPrefStore>( |
| 103 | overlay.get(), user_pref_store_.get()); |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 104 | |
Ramin Halavati | f623bafe9 | 2018-07-17 12:12:58 | [diff] [blame] | 105 | for (const char* persistent_pref_name : persistent_pref_names) |
| 106 | incognito_pref_store->RegisterPersistentPref(persistent_pref_name); |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 107 | |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 108 | 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 Degros | 9d35fc57 | 2018-02-05 22:32:45 | [diff] [blame] | 117 | return std::make_unique<PrefServiceSyncable>( |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 118 | std::move(pref_notifier), std::move(pref_value_store), |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 119 | std::move(incognito_pref_store), std::move(forked_registry), |
maxbogue | ea16ff41 | 2016-10-28 16:35:29 | [diff] [blame] | 120 | pref_sync_associator_.client(), read_error_callback_, false); |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | bool PrefServiceSyncable::IsSyncing() { |
| 124 | return pref_sync_associator_.models_associated(); |
| 125 | } |
| 126 | |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 127 | bool PrefServiceSyncable::IsPrioritySyncing() { |
| 128 | return priority_pref_sync_associator_.models_associated(); |
| 129 | } |
| 130 | |
[email protected] | f3ca909 | 2013-05-26 02:25:15 | [diff] [blame] | 131 | bool 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] | 57f6212 | 2013-01-14 00:59:24 | [diff] [blame] | 136 | void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver* observer) { |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 137 | observer_list_.AddObserver(observer); |
| 138 | } |
| 139 | |
[email protected] | 57f6212 | 2013-01-14 00:59:24 | [diff] [blame] | 140 | void PrefServiceSyncable::RemoveObserver( |
| 141 | PrefServiceSyncableObserver* observer) { |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 142 | observer_list_.RemoveObserver(observer); |
| 143 | } |
| 144 | |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 145 | syncer::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 Kotenkov | 75b1c3a | 2017-10-24 14:47:24 | [diff] [blame] | 153 | return nullptr; |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 154 | } |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | void 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 | |
sdefresne | 0b1722f0 | 2015-09-14 18:12:12 | [diff] [blame] | 165 | void PrefServiceSyncable::AddSyncedPrefObserver(const std::string& name, |
| 166 | SyncedPrefObserver* observer) { |
[email protected] | 0ebc403 | 2013-08-10 07:07:11 | [diff] [blame] | 167 | pref_sync_associator_.AddSyncedPrefObserver(name, observer); |
| 168 | priority_pref_sync_associator_.AddSyncedPrefObserver(name, observer); |
| 169 | } |
| 170 | |
| 171 | void 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 | |
lshang | 2cf5c57 | 2016-07-15 01:36:32 | [diff] [blame] | 178 | void PrefServiceSyncable::RegisterMergeDataFinishedCallback( |
| 179 | const base::Closure& callback) { |
| 180 | pref_sync_associator_.RegisterMergeDataFinishedCallback(callback); |
| 181 | } |
| 182 | |
raymes | 25fb8e7f | 2015-04-27 01:23:10 | [diff] [blame] | 183 | void PrefServiceSyncable::AddRegisteredSyncablePreference( |
| 184 | const std::string& path, |
avi | 5dd91f8 | 2015-12-25 22:30:46 | [diff] [blame] | 185 | uint32_t flags) { |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 186 | DCHECK(FindPreference(path)); |
raymes | 51b41a6 | 2015-04-24 02:45:04 | [diff] [blame] | 187 | if (flags & user_prefs::PrefRegistrySyncable::SYNCABLE_PREF) { |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 188 | DCHECK(!pref_sync_associator_.models_associated() || |
| 189 | pref_registry_->IsWhitelistedLateRegistrationPref(path)); |
| 190 | pref_sync_associator_.RegisterPref(path); |
sdefresne | 0b1722f0 | 2015-09-14 18:12:12 | [diff] [blame] | 191 | } else if (flags & user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) { |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 192 | DCHECK(!priority_pref_sync_associator_.models_associated() || |
| 193 | pref_registry_->IsWhitelistedLateRegistrationPref(path)); |
| 194 | priority_pref_sync_associator_.RegisterPref(path); |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 195 | } |
[email protected] | c753f14 | 2013-02-10 13:14:04 | [diff] [blame] | 196 | } |
| 197 | |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 198 | void PrefServiceSyncable::OnIsSyncingChanged() { |
ericwilligers | ff2af33 | 2016-10-19 00:16:50 | [diff] [blame] | 199 | for (auto& observer : observer_list_) |
| 200 | observer.OnIsSyncingChanged(); |
[email protected] | 5b19952 | 2012-12-22 17:24:44 | [diff] [blame] | 201 | } |
[email protected] | 43fe640e | 2013-03-27 22:18:55 | [diff] [blame] | 202 | |
| 203 | void PrefServiceSyncable::ProcessPrefChange(const std::string& name) { |
| 204 | pref_sync_associator_.ProcessPrefChange(name); |
| 205 | priority_pref_sync_associator_.ProcessPrefChange(name); |
| 206 | } |
sdefresne | 50c1e52 | 2015-09-18 09:47:51 | [diff] [blame] | 207 | |
maxbogue | ea16ff41 | 2016-10-28 16:35:29 | [diff] [blame] | 208 | } // namespace sync_preferences |