Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / components / sync_preferences / pref_model_associator.h
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_SYNC_PREFERENCES_PREF_MODEL_ASSOCIATOR_H_
6 #define COMPONENTS_SYNC_PREFERENCES_PREF_MODEL_ASSOCIATOR_H_
7
8 #include <memory>
9 #include <set>
10 #include <string>
11 #include <unordered_map>
12
13 #include "base/callback_forward.h"
14 #include "base/compiler_specific.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/sequence_checker.h"
18 #include "components/sync/model/sync_data.h"
19 #include "components/sync/model/syncable_service.h"
20 #include "components/sync_preferences/synced_pref_observer.h"
21
22 class PersistentPrefStore;
23
24 namespace base {
25 class Value;
26 }
27
28 namespace sync_pb {
29 class EntitySpecifics;
30 class PreferenceSpecifics;
31 }  // namespace sync_pb
32
33 namespace sync_preferences {
34
35 class PrefModelAssociatorClient;
36 class PrefServiceSyncable;
37
38 // Contains all preference sync related logic.
39 // TODO(sync): Merge this into PrefService once we separate the profile
40 // PrefService from the local state PrefService.
41 class PrefModelAssociator : public syncer::SyncableService {
42  public:
43   // Constructs a PrefModelAssociator initializing the |client_| and |type_|
44   // instance variable. The |client| and |user_pref_store| are not owned by this
45   // object and they must outlive the PrefModelAssociator.
46   PrefModelAssociator(const PrefModelAssociatorClient* client,
47                       syncer::ModelType type,
48                       PersistentPrefStore* user_pref_store);
49
50   PrefModelAssociator(const PrefModelAssociator&) = delete;
51   PrefModelAssociator& operator=(const PrefModelAssociator&) = delete;
52
53   ~PrefModelAssociator() override;
54
55   // See description above field for details.
56   bool models_associated() const { return models_associated_; }
57
58   // Returns the mutable preference from |specifics| for a given model |type|.
59   // Exposed for testing.
60   static sync_pb::PreferenceSpecifics* GetMutableSpecifics(
61       syncer::ModelType type,
62       sync_pb::EntitySpecifics* specifics);
63
64   // syncer::SyncableService implementation.
65   void WaitUntilReadyToSync(base::OnceClosure done) override;
66   absl::optional<syncer::ModelError> MergeDataAndStartSyncing(
67       syncer::ModelType type,
68       const syncer::SyncDataList& initial_sync_data,
69       std::unique_ptr<syncer::SyncChangeProcessor> sync_processor,
70       std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) override;
71   void StopSyncing(syncer::ModelType type) override;
72   absl::optional<syncer::ModelError> ProcessSyncChanges(
73       const base::Location& from_here,
74       const syncer::SyncChangeList& change_list) override;
75   // Note for GetAllSyncDataForTesting: This will build a model of all
76   // preferences registered as syncable with user controlled data. We do not
77   // track any information for preferences not registered locally as syncable
78   // and do not inform the syncer of non-user controlled preferences.
79   syncer::SyncDataList GetAllSyncDataForTesting(syncer::ModelType type) const;
80
81   // Register a preference with the specified name for syncing. We do not care
82   // about the type at registration time, but when changes arrive from the
83   // syncer, we check if they can be applied and if not drop them.
84   // Note: This should only be called at profile startup time (before sync
85   // begins).
86   void RegisterPref(const std::string& name);
87
88   // See |legacy_model_type_preferences_|.
89   void RegisterPrefWithLegacyModelType(const std::string& name);
90
91   // Process a local preference change. This can trigger new SyncChanges being
92   // sent to the syncer.
93   void ProcessPrefChange(const std::string& name);
94
95   void SetPrefService(PrefServiceSyncable* pref_service);
96
97   // Merges the local_value into the supplied server_value and returns
98   // the result (caller takes ownership). If there is a conflict, the server
99   // value always takes precedence. Note that only certain preferences will
100   // actually be merged, all others will return a copy of the server value. See
101   // the method's implementation for details.
102   base::Value MergePreference(const std::string& name,
103                               const base::Value& local_value,
104                               const base::Value& server_value);
105
106   // Fills |sync_data| with a sync representation of the preference data
107   // provided.
108   bool CreatePrefSyncData(const std::string& name,
109                           const base::Value& value,
110                           syncer::SyncData* sync_data) const;
111
112   // Returns true if the specified preference is registered for syncing.
113   bool IsPrefRegistered(const std::string& name) const;
114
115   // See |legacy_model_type_preferences_|.
116   // Exposed for testing.
117   bool IsLegacyModelTypePref(const std::string& name) const;
118
119   // Adds a SyncedPrefObserver to watch for changes to a specific pref.
120   void AddSyncedPrefObserver(const std::string& name,
121                              SyncedPrefObserver* observer);
122
123   // Removes a SyncedPrefObserver from a pref's list of observers.
124   void RemoveSyncedPrefObserver(const std::string& name,
125                                 SyncedPrefObserver* observer);
126
127   // Returns the PrefModelAssociatorClient for this object.
128   const PrefModelAssociatorClient* client() const { return client_; }
129
130   // Returns true if the pref under the given name is pulled down from sync.
131   // Note this does not refer to SYNCABLE_PREF.
132   bool IsPrefSyncedForTesting(const std::string& name) const;
133
134  private:
135   // Create an association for a given preference. If |sync_pref| is valid,
136   // signifying that sync has data for this preference, we reconcile their data
137   // with ours and append a new UPDATE SyncChange to |sync_changes|. If
138   // sync_pref is not set, we append an ADD SyncChange to |sync_changes| with
139   // the current preference data.
140   // Note: We do not modify the sync data for preferences that are either
141   // controlled by policy (are not user modifiable) or have their default value
142   // (are not user controlled).
143   void InitPrefAndAssociate(const syncer::SyncData& sync_pref,
144                             const std::string& pref_name,
145                             syncer::SyncChangeList* sync_changes);
146
147   static std::unique_ptr<base::Value> MergeListValues(
148       const base::Value& from_value,
149       const base::Value& to_value);
150
151   static base::Value MergeDictionaryValues(const base::Value& from_value,
152                                            const base::Value& to_value);
153
154   // Extract preference value from sync specifics.
155   static absl::optional<base::Value> ReadPreferenceSpecifics(
156       const sync_pb::PreferenceSpecifics& specifics);
157
158   void NotifySyncedPrefObservers(const std::string& path, bool from_sync) const;
159
160   // Sets |pref_name| to |new_value| if |new_value| has an appropriate type for
161   // this preference. Otherwise records metrics and logs a warning.
162   void SetPrefWithTypeCheck(const std::string& pref_name,
163                             const base::Value& new_value);
164
165   // Returns true if the |new_value| for |pref_name| has the same type as the
166   // existing value in the user's local pref store. If the types don't match,
167   // records metrics and logs a warning.
168   bool TypeMatchesUserPrefStore(const std::string& pref_name,
169                                 const base::Value& new_value) const;
170
171   // Verifies that the type which preference |pref_name| was registered with
172   // matches the type of any persisted value. On mismatch, the persisted value
173   // gets removed.
174   void EnforceRegisteredTypeInStore(const std::string& pref_name);
175
176   // Notifies the synced pref observers that the pref for the given |path| is
177   // synced.
178   void NotifyStartedSyncing(const std::string& path) const;
179
180   // Do we have an active association between the preferences and sync models?
181   // Set when start syncing, reset in StopSyncing. While this is not set, we
182   // ignore any local preference changes (when we start syncing we will look
183   // up the most recent values anyways).
184   bool models_associated_ = false;
185
186   // Whether we're currently processing changes from the syncer. While this is
187   // true, we ignore any local preference changes, since we triggered them.
188   bool processing_syncer_changes_ = false;
189
190   // A set of preference names.
191   typedef std::set<std::string> PreferenceSet;
192
193   // All preferences that have registered as being syncable with this profile.
194   PreferenceSet registered_preferences_;
195
196   // The preferences that are currently synced (excludes those preferences
197   // that have never had sync data and currently have default values or are
198   // policy controlled).
199   // Note: this set never decreases, only grows to eventually match
200   // registered_preferences_ as more preferences are synced. It determines
201   // whether a preference change should update an existing sync node or create
202   // a new sync node.
203   PreferenceSet synced_preferences_;
204
205   // Preferences that have migrated to a new ModelType. They are included here
206   // so updates can be sent back to older clients with this old ModelType.
207   // Updates received from older clients will be ignored. The common case is
208   // migration from PREFERENCES to OS_PREFERENCES. This field can be removed
209   // after 10/2020.
210   PreferenceSet legacy_model_type_preferences_;
211
212   // The PrefService we are syncing to.
213   raw_ptr<PrefServiceSyncable> pref_service_ = nullptr;
214
215   // Sync's syncer::SyncChange handler. We push all our changes through this.
216   std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_;
217
218   // Sync's error handler. We use this to create sync errors.
219   std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory_;
220
221   // The datatype that this associator is responible for, either PREFERENCES or
222   // PRIORITY_PREFERENCES or OS_PREFERENCES or OS_PRIORITY_PREFERENCES.
223   syncer::ModelType type_;
224
225   // Map prefs to lists of observers. Observers will receive notification when
226   // a pref changes, including the detail of whether or not the change came
227   // from sync.
228   using SyncedPrefObserverList =
229       base::ObserverList<SyncedPrefObserver>::Unchecked;
230   std::unordered_map<std::string, std::unique_ptr<SyncedPrefObserverList>>
231       synced_pref_observers_;
232   raw_ptr<const PrefModelAssociatorClient> client_;  // Weak.
233
234   const raw_ptr<PersistentPrefStore> user_pref_store_;
235
236   SEQUENCE_CHECKER(sequence_checker_);
237 };
238
239 }  // namespace sync_preferences
240
241 #endif  // COMPONENTS_SYNC_PREFERENCES_PREF_MODEL_ASSOCIATOR_H_