pref_model_associator.h 10 KB

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