| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_SYNC_PREFERENCES_SYNCABLE_PREFS_DATABASE_H_ |
| #define COMPONENTS_SYNC_PREFERENCES_SYNCABLE_PREFS_DATABASE_H_ |
| |
| #include <optional> |
| #include <ostream> |
| #include <string_view> |
| |
| #include "base/check.h" |
| #include "build/build_config.h" |
| #include "components/sync/base/data_type.h" |
| #include "components/sync/base/user_selectable_type.h" |
| |
| namespace sync_preferences { |
| |
| // TODO(crbug.com/412602018): Rename enum and enum values to better reflect |
| // their purpose. |
| enum class PrefSensitivity { |
| // The pref is not sensitive and requires only the preference sync toggle to |
| // be enabled for syncing. |
| kNone, |
| // The pref contains sensitive information and requires history opt-in to |
| // allow syncing. |
| kSensitiveRequiresHistory, |
| // The pref is exempt from user control and hence, decoupled from any user |
| // toggle. Note that this is only supported for priority prefs. |
| kExemptFromUserControlWhileSignedIn, |
| }; |
| |
| enum class MergeBehavior { |
| // The account value wins. This is the default behavior. Any pref update is |
| // applied to both - the local value as well as the account value. |
| kNone, |
| // For dictionary values, all entries in `account_value` and `local_value` are |
| // merged recursively. In case of a conflict, the entry from `account_value` |
| // wins. With a DualLayerUserPrefStore, pref updates are split between the |
| // account value and the local value and only the relevant updates are applied |
| // to each. |
| kMergeableDict, |
| // For list values, all entries of `account_value` come first, followed by all |
| // entries in the `local_value`. Any repeating entry in `local_value` is |
| // omitted. Any pref update overwrites both - the local value as well as the |
| // account value. |
| kMergeableListWithRewriteOnUpdate, |
| // A custom merge logic has been implemented for this pref. |
| kCustom |
| }; |
| |
| // This class represents the metadata corresponding to a syncable preference. |
| class SyncablePrefMetadata { |
| public: |
| constexpr SyncablePrefMetadata(int syncable_pref_id, |
| syncer::DataType data_type, |
| PrefSensitivity pref_sensitivity, |
| MergeBehavior merge_behavior) |
| : syncable_pref_id_(syncable_pref_id), |
| data_type_(data_type), |
| pref_sensitivity_(pref_sensitivity), |
| merge_behaviour_(merge_behavior) { |
| CHECK(data_type_ == syncer::PREFERENCES || |
| data_type_ == syncer::PRIORITY_PREFERENCES |
| #if BUILDFLAG(IS_CHROMEOS) |
| || data_type_ == syncer::OS_PREFERENCES || |
| data_type_ == syncer::OS_PRIORITY_PREFERENCES |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| ) |
| << "Invalid type " << data_type_ |
| << " for syncable pref with id=" << syncable_pref_id_; |
| CHECK(pref_sensitivity_ != |
| PrefSensitivity::kExemptFromUserControlWhileSignedIn || |
| data_type_ == syncer::PRIORITY_PREFERENCES) |
| << "Always syncing prefs must be priority prefs."; |
| } |
| |
| // Returns the unique ID corresponding to the syncable preference. |
| int syncable_pref_id() const { return syncable_pref_id_; } |
| // Returns the data type of the pref, i.e. PREFERENCES, PRIORITY_PREFERENCES, |
| // OS_PREFERENCES or OS_PRIORITY_PREFERENCES. |
| syncer::DataType data_type() const { return data_type_; } |
| |
| // Returns the sensitivity of the pref. It is used to determine whether the |
| // pref requires history opt-in. |
| PrefSensitivity pref_sensitivity() const { return pref_sensitivity_; } |
| |
| // Returns whether the pref requires history opt-in to be synced. |
| bool is_history_opt_in_required() const { |
| return pref_sensitivity() == PrefSensitivity::kSensitiveRequiresHistory; |
| } |
| |
| MergeBehavior merge_behavior() const { return merge_behaviour_; } |
| |
| private: |
| int syncable_pref_id_; |
| syncer::DataType data_type_; |
| PrefSensitivity pref_sensitivity_; |
| MergeBehavior merge_behaviour_; |
| }; |
| |
| // This class provides an interface to define the list of syncable |
| // preferences (and in the future, some additional metadata). |
| // PrefModelAssociatorClient uses the interface to verify if a preference is |
| // syncable. Platform-specific preferences should be part of individual |
| // implementations of this interface. |
| class SyncablePrefsDatabase { |
| public: |
| SyncablePrefsDatabase() = default; |
| virtual ~SyncablePrefsDatabase() = default; |
| SyncablePrefsDatabase(const SyncablePrefsDatabase&) = delete; |
| SyncablePrefsDatabase& operator=(const SyncablePrefsDatabase&) = delete; |
| |
| // Returns the metadata associated to the pref and null if `pref_name` is not |
| // syncable. |
| virtual std::optional<SyncablePrefMetadata> GetSyncablePrefMetadata( |
| std::string_view pref_name) const = 0; |
| |
| // Returns true if `pref_name` is part of the allowlist of syncable |
| // preferences. |
| bool IsPreferenceSyncable(std::string_view pref_name) const; |
| |
| // Return true if `pref_name` is a mergeable syncable preference. |
| // Note: `pref_name` must be syncable. |
| bool IsPreferenceMergeable(std::string_view pref_name) const; |
| |
| // Returns whether `pref_name` is part of the allowlist of preferences that |
| // are always synced, irrespective of the preference sync user toggle. |
| bool IsPreferenceAlwaysSyncing(std::string_view pref_name) const; |
| }; |
| |
| } // namespace sync_preferences |
| |
| #endif // COMPONENTS_SYNC_PREFERENCES_SYNCABLE_PREFS_DATABASE_H_ |