1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/sync_preferences/pref_service_syncable.h"
- #include <stdint.h>
- #include <memory>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/json/json_reader.h"
- #include "base/json/json_string_value_serializer.h"
- #include "base/json/json_writer.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/raw_ptr.h"
- #include "base/strings/utf_string_conversions.h"
- #include "build/chromeos_buildflags.h"
- #include "components/pref_registry/pref_registry_syncable.h"
- #include "components/prefs/pref_notifier_impl.h"
- #include "components/prefs/scoped_user_pref_update.h"
- #include "components/prefs/testing_pref_store.h"
- #include "components/sync/base/client_tag_hash.h"
- #include "components/sync/base/model_type.h"
- #include "components/sync/model/sync_change.h"
- #include "components/sync/model/sync_change_processor.h"
- #include "components/sync/model/sync_data.h"
- #include "components/sync/model/syncable_service.h"
- #include "components/sync/protocol/entity_specifics.pb.h"
- #include "components/sync/protocol/preference_specifics.pb.h"
- #include "components/sync/test/sync_error_factory_mock.h"
- #include "components/sync_preferences/pref_model_associator.h"
- #include "components/sync_preferences/pref_model_associator_client.h"
- #include "components/sync_preferences/pref_service_syncable_observer.h"
- #include "components/sync_preferences/synced_pref_observer.h"
- #include "components/sync_preferences/testing_pref_service_syncable.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- #include "ash/constants/ash_features.h"
- #include "base/test/scoped_feature_list.h"
- #include "testing/gmock/include/gmock/gmock-matchers.h"
- #endif
- using syncer::ModelType;
- using syncer::ModelTypeSet;
- using syncer::SyncChange;
- using syncer::SyncData;
- using testing::Eq;
- using testing::IsEmpty;
- using testing::Matches;
- using testing::NotNull;
- using testing::UnorderedElementsAre;
- using user_prefs::PrefRegistrySyncable;
- namespace sync_preferences {
- namespace {
- const char kExampleUrl0[] = "http://example.com/0";
- const char kExampleUrl1[] = "http://example.com/1";
- const char kExampleUrl2[] = "http://example.com/2";
- const char kStringPrefName[] = "string_pref_name";
- const char kListPrefName[] = "list_pref_name";
- const char kDictPrefName[] = "dict_pref_name";
- const char kUnsyncedPreferenceName[] = "nonsense_pref_name";
- const char kUnsyncedPreferenceDefaultValue[] = "default";
- const char kDefaultCharsetPrefName[] = "default_charset";
- const char kNonDefaultCharsetValue[] = "foo";
- const char kDefaultCharsetValue[] = "utf-8";
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- constexpr ModelTypeSet kAllPreferenceModelTypes(
- syncer::PREFERENCES,
- syncer::PRIORITY_PREFERENCES,
- syncer::OS_PREFERENCES,
- syncer::OS_PRIORITY_PREFERENCES);
- MATCHER_P(MatchesModelType, model_type, "") {
- const syncer::SyncChange& sync_change = arg;
- return Matches(model_type)(sync_change.sync_data().GetDataType());
- }
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
- public:
- explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
- : output_(output) {}
- absl::optional<syncer::ModelError> ProcessSyncChanges(
- const base::Location& from_here,
- const syncer::SyncChangeList& change_list) override {
- if (output_) {
- output_->insert(output_->end(), change_list.begin(), change_list.end());
- }
- if (fail_next_) {
- fail_next_ = false;
- return syncer::ModelError(FROM_HERE, "Error");
- }
- return absl::nullopt;
- }
- void FailNextProcessSyncChanges() { fail_next_ = true; }
- private:
- raw_ptr<syncer::SyncChangeList> output_;
- bool fail_next_ = false;
- };
- class TestSyncedPrefObserver : public SyncedPrefObserver {
- public:
- TestSyncedPrefObserver() = default;
- ~TestSyncedPrefObserver() = default;
- void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
- last_pref_ = path;
- changed_count_++;
- }
- void OnStartedSyncing(const std::string& path) override {
- synced_pref_ = path;
- sync_started_count_++;
- }
- std::string last_pref_;
- int changed_count_ = 0;
- std::string synced_pref_;
- int sync_started_count_ = 0;
- };
- class TestPrefServiceSyncableObserver : public PrefServiceSyncableObserver {
- public:
- TestPrefServiceSyncableObserver() = default;
- ~TestPrefServiceSyncableObserver() override = default;
- void OnIsSyncingChanged() override {
- if (sync_pref_observer_ && sync_pref_observer_->sync_started_count_ > 0) {
- is_syncing_changed_ = true;
- }
- }
- void SetSyncedPrefObserver(const TestSyncedPrefObserver* sync_pref_observer) {
- sync_pref_observer_ = sync_pref_observer;
- }
- bool is_syncing_changed() { return is_syncing_changed_; }
- private:
- bool is_syncing_changed_ = false;
- raw_ptr<const TestSyncedPrefObserver> sync_pref_observer_ = nullptr;
- };
- syncer::SyncChange MakeRemoteChange(const std::string& name,
- const base::Value& value,
- SyncChange::SyncChangeType change_type,
- syncer::ModelType model_type) {
- std::string serialized;
- JSONStringValueSerializer json(&serialized);
- bool success = json.Serialize(value);
- DCHECK(success);
- sync_pb::EntitySpecifics entity;
- sync_pb::PreferenceSpecifics* pref =
- PrefModelAssociator::GetMutableSpecifics(model_type, &entity);
- pref->set_name(name);
- pref->set_value(serialized);
- return syncer::SyncChange(
- FROM_HERE, change_type,
- syncer::SyncData::CreateRemoteData(
- entity, syncer::ClientTagHash::FromUnhashed(model_type, name)));
- }
- // Creates a SyncChange for model type |PREFERENCES|.
- syncer::SyncChange MakeRemoteChange(const std::string& name,
- const base::Value& value,
- SyncChange::SyncChangeType type) {
- return MakeRemoteChange(name, value, type, syncer::ModelType::PREFERENCES);
- }
- // Creates SyncData for a remote pref change.
- SyncData CreateRemoteSyncData(const std::string& name,
- const base::Value& value) {
- std::string serialized;
- JSONStringValueSerializer json(&serialized);
- EXPECT_TRUE(json.Serialize(value));
- sync_pb::EntitySpecifics one;
- sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
- pref_one->set_name(name);
- pref_one->set_value(serialized);
- return SyncData::CreateRemoteData(
- one, syncer::ClientTagHash::FromUnhashed(syncer::ModelType::PREFERENCES,
- name));
- }
- class PrefServiceSyncableTest : public testing::Test {
- public:
- PrefServiceSyncableTest() = default;
- void SetUp() override {
- prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName,
- kUnsyncedPreferenceDefaultValue);
- prefs_.registry()->RegisterStringPref(
- kStringPrefName, std::string(),
- user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- prefs_.registry()->RegisterListPref(
- kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- prefs_.registry()->RegisterStringPref(
- kDefaultCharsetPrefName, kDefaultCharsetValue,
- user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- pref_sync_service_ = static_cast<PrefModelAssociator*>(
- prefs_.GetSyncableService(syncer::PREFERENCES));
- ASSERT_TRUE(pref_sync_service_);
- }
- void AddToRemoteDataList(const std::string& name,
- const base::Value& value,
- syncer::SyncDataList* out) {
- out->push_back(CreateRemoteSyncData(name, value));
- }
- void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
- syncer::SyncChangeList* output) {
- absl::optional<syncer::ModelError> error =
- pref_sync_service_->MergeDataAndStartSyncing(
- syncer::PREFERENCES, initial_data,
- std::make_unique<TestSyncProcessorStub>(output),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_FALSE(error.has_value());
- }
- void InitWithNoSyncData() {
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), nullptr);
- }
- const base::Value& GetPreferenceValue(const std::string& name) {
- const PrefService::Preference* preference =
- prefs_.FindPreference(name.c_str());
- return *preference->GetValue();
- }
- std::unique_ptr<base::Value> FindValue(const std::string& name,
- const syncer::SyncChangeList& list) {
- auto it = list.begin();
- for (; it != list.end(); ++it) {
- if (it->sync_data().GetClientTagHash() ==
- syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)) {
- return base::JSONReader::ReadDeprecated(
- it->sync_data().GetSpecifics().preference().value());
- }
- }
- return nullptr;
- }
- bool IsRegistered(const std::string& pref_name) {
- return pref_sync_service_->IsPrefRegistered(pref_name.c_str());
- }
- PrefService* GetPrefs() { return &prefs_; }
- TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; }
- protected:
- TestingPrefServiceSyncable prefs_;
- raw_ptr<PrefModelAssociator> pref_sync_service_ = nullptr;
- };
- TEST_F(PrefServiceSyncableTest, CreatePrefSyncData) {
- prefs_.SetString(kStringPrefName, kExampleUrl0);
- const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
- syncer::SyncData sync_data;
- EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(
- pref->name(), *pref->GetValue(), &sync_data));
- EXPECT_EQ(
- syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, kStringPrefName),
- sync_data.GetClientTagHash());
- const sync_pb::PreferenceSpecifics& specifics(
- sync_data.GetSpecifics().preference());
- EXPECT_EQ(std::string(kStringPrefName), specifics.name());
- std::unique_ptr<base::Value> value =
- base::JSONReader::ReadDeprecated(specifics.value());
- EXPECT_EQ(*pref->GetValue(), *value);
- }
- TEST_F(PrefServiceSyncableTest, ModelAssociationDoNotSyncDefaults) {
- const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
- EXPECT_TRUE(pref->IsDefaultValue());
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- EXPECT_TRUE(IsRegistered(kStringPrefName));
- EXPECT_TRUE(pref->IsDefaultValue());
- EXPECT_FALSE(FindValue(kStringPrefName, out).get());
- }
- TEST_F(PrefServiceSyncableTest, ModelAssociationEmptyCloud) {
- prefs_.SetString(kStringPrefName, kExampleUrl0);
- {
- ListPrefUpdate update(GetPrefs(), kListPrefName);
- base::Value* url_list = update.Get();
- url_list->Append(kExampleUrl0);
- url_list->Append(kExampleUrl1);
- }
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- std::unique_ptr<base::Value> value(FindValue(kStringPrefName, out));
- ASSERT_TRUE(value.get());
- EXPECT_EQ(GetPreferenceValue(kStringPrefName), *value);
- value = FindValue(kListPrefName, out);
- ASSERT_TRUE(value.get());
- EXPECT_EQ(GetPreferenceValue(kListPrefName), *value);
- }
- TEST_F(PrefServiceSyncableTest, ModelAssociationCloudHasData) {
- prefs_.SetString(kStringPrefName, kExampleUrl0);
- {
- ListPrefUpdate update(GetPrefs(), kListPrefName);
- base::Value* url_list = update.Get();
- url_list->Append(kExampleUrl0);
- }
- syncer::SyncDataList in;
- syncer::SyncChangeList out;
- AddToRemoteDataList(kStringPrefName, base::Value(kExampleUrl1), &in);
- base::ListValue urls_to_restore;
- urls_to_restore.Append(kExampleUrl1);
- AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
- AddToRemoteDataList(kDefaultCharsetPrefName,
- base::Value(kNonDefaultCharsetValue), &in);
- InitWithSyncDataTakeOutput(in, &out);
- ASSERT_FALSE(FindValue(kStringPrefName, out).get());
- ASSERT_FALSE(FindValue(kDefaultCharsetPrefName, out).get());
- EXPECT_EQ(kExampleUrl1, prefs_.GetString(kStringPrefName));
- // No associator client is registered, so lists and dictionaries should not
- // get merged (remote write wins).
- auto expected_urls = std::make_unique<base::ListValue>();
- expected_urls->Append(kExampleUrl1);
- EXPECT_FALSE(FindValue(kListPrefName, out));
- EXPECT_EQ(GetPreferenceValue(kListPrefName), *expected_urls);
- EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName));
- }
- // Verifies that the implementation gracefully handles an initial remote sync
- // data of wrong type. The local version should not get modified in these cases.
- TEST_F(PrefServiceSyncableTest, ModelAssociationWithDataTypeMismatch) {
- prefs_.SetString(kStringPrefName, kExampleUrl0);
- syncer::SyncDataList in;
- base::Value remote_int_value(123);
- AddToRemoteDataList(kStringPrefName, remote_int_value, &in);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- EXPECT_THAT(out, IsEmpty());
- EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
- }
- class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
- public:
- TestPrefModelAssociatorClient() = default;
- TestPrefModelAssociatorClient(const TestPrefModelAssociatorClient&) = delete;
- TestPrefModelAssociatorClient& operator=(
- const TestPrefModelAssociatorClient&) = delete;
- ~TestPrefModelAssociatorClient() override = default;
- // PrefModelAssociatorClient implementation.
- bool IsMergeableListPreference(const std::string& pref_name) const override {
- return pref_name == kListPrefName;
- }
- bool IsMergeableDictionaryPreference(
- const std::string& pref_name) const override {
- return is_dict_pref_;
- }
- base::Value MaybeMergePreferenceValues(
- const std::string& pref_name,
- const base::Value& local_value,
- const base::Value& server_value) const override {
- return base::Value();
- }
- void SetIsDictPref(bool is_dict_pref) { is_dict_pref_ = is_dict_pref; }
- private:
- bool is_dict_pref_ = true;
- };
- class PrefServiceSyncableMergeTest : public testing::Test {
- public:
- PrefServiceSyncableMergeTest()
- : prefs_(
- std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
- std::make_unique<PrefValueStore>(managed_prefs_.get(),
- new TestingPrefStore,
- new TestingPrefStore,
- new TestingPrefStore,
- new TestingPrefStore,
- user_prefs_.get(),
- standalone_browser_prefs_.get(),
- pref_registry_->defaults().get(),
- pref_notifier_),
- user_prefs_,
- standalone_browser_prefs_,
- pref_registry_,
- &client_,
- /*read_error_callback=*/base::DoNothing(),
- /*async=*/false) {}
- void SetUp() override {
- pref_registry_->RegisterStringPref(kUnsyncedPreferenceName,
- kUnsyncedPreferenceDefaultValue);
- pref_registry_->RegisterStringPref(
- kStringPrefName, std::string(),
- user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- pref_registry_->RegisterListPref(
- kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- pref_registry_->RegisterDictionaryPref(
- kDictPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- pref_registry_->RegisterStringPref(
- kDefaultCharsetPrefName, kDefaultCharsetValue,
- user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- pref_sync_service_ = static_cast<PrefModelAssociator*>(
- prefs_.GetSyncableService(syncer::PREFERENCES));
- ASSERT_THAT(pref_sync_service_, NotNull());
- }
- syncer::SyncChange MakeRemoteChange(const std::string& name,
- const base::Value& value,
- SyncChange::SyncChangeType type) {
- std::string serialized;
- JSONStringValueSerializer json(&serialized);
- CHECK(json.Serialize(value));
- sync_pb::EntitySpecifics entity;
- sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference();
- pref_one->set_name(name);
- pref_one->set_value(serialized);
- return syncer::SyncChange(FROM_HERE, type,
- syncer::SyncData::CreateRemoteData(
- entity, syncer::ClientTagHash::FromUnhashed(
- syncer::PREFERENCES, name)));
- }
- void AddToRemoteDataList(const std::string& name,
- const base::Value& value,
- syncer::SyncDataList* out) {
- std::string serialized;
- JSONStringValueSerializer json(&serialized);
- ASSERT_TRUE(json.Serialize(value));
- sync_pb::EntitySpecifics one;
- sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
- pref_one->set_name(name);
- pref_one->set_value(serialized);
- out->push_back(SyncData::CreateRemoteData(
- one, syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)));
- }
- void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
- syncer::SyncChangeList* output) {
- absl::optional<syncer::ModelError> error =
- pref_sync_service_->MergeDataAndStartSyncing(
- syncer::PREFERENCES, initial_data,
- std::make_unique<TestSyncProcessorStub>(output),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_FALSE(error.has_value());
- }
- const base::Value& GetPreferenceValue(const std::string& name) {
- const PrefService::Preference* preference =
- prefs_.FindPreference(name.c_str());
- return *preference->GetValue();
- }
- std::unique_ptr<base::Value> FindValue(const std::string& name,
- const syncer::SyncChangeList& list) {
- auto it = list.begin();
- for (; it != list.end(); ++it) {
- if (it->sync_data().GetClientTagHash() ==
- syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)) {
- return base::JSONReader::ReadDeprecated(
- it->sync_data().GetSpecifics().preference().value());
- }
- }
- return nullptr;
- }
- protected:
- scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_ =
- base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
- // Owned by prefs_;
- const raw_ptr<PrefNotifierImpl> pref_notifier_ = new PrefNotifierImpl;
- scoped_refptr<TestingPrefStore> managed_prefs_ =
- base::MakeRefCounted<TestingPrefStore>();
- scoped_refptr<TestingPrefStore> user_prefs_ =
- base::MakeRefCounted<TestingPrefStore>();
- scoped_refptr<TestingPrefStore> standalone_browser_prefs_ =
- base::MakeRefCounted<TestingPrefStore>();
- TestPrefModelAssociatorClient client_;
- PrefServiceSyncable prefs_;
- raw_ptr<PrefModelAssociator> pref_sync_service_ = nullptr;
- };
- TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedListValues) {
- {
- ListPrefUpdate update(&prefs_, kListPrefName);
- base::Value* url_list = update.Get();
- url_list->Append(kExampleUrl0);
- url_list->Append(kExampleUrl1);
- }
- base::ListValue urls_to_restore;
- urls_to_restore.Append(kExampleUrl1);
- urls_to_restore.Append(kExampleUrl2);
- syncer::SyncDataList in;
- AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- std::unique_ptr<base::ListValue> expected_urls(new base::ListValue);
- expected_urls->Append(kExampleUrl1);
- expected_urls->Append(kExampleUrl2);
- expected_urls->Append(kExampleUrl0);
- std::unique_ptr<base::Value> value(FindValue(kListPrefName, out));
- ASSERT_TRUE(value.get());
- EXPECT_EQ(*value, *expected_urls) << *value;
- EXPECT_EQ(GetPreferenceValue(kListPrefName), *expected_urls);
- }
- // List preferences have special handling at association time due to our ability
- // to merge the local and sync value. Make sure the merge logic doesn't merge
- // managed preferences.
- TEST_F(PrefServiceSyncableMergeTest, ManagedListPreferences) {
- // Make the list of urls to restore on startup managed.
- base::Value managed_value(base::Value::Type::LIST);
- managed_value.Append(kExampleUrl0);
- managed_value.Append(kExampleUrl1);
- managed_prefs_->SetValue(kListPrefName,
- base::Value::ToUniquePtrValue(managed_value.Clone()),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- // Set a cloud version.
- syncer::SyncDataList in;
- base::ListValue urls_to_restore;
- urls_to_restore.Append(kExampleUrl1);
- urls_to_restore.Append(kExampleUrl2);
- AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
- // Start sync and verify the synced value didn't get merged.
- {
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- EXPECT_FALSE(FindValue(kListPrefName, out).get());
- }
- // Changing the user's urls to restore on startup pref should not sync
- // anything.
- {
- syncer::SyncChangeList out;
- base::ListValue user_value;
- user_value.Append("http://chromium.org");
- prefs_.Set(kListPrefName, user_value);
- EXPECT_FALSE(FindValue(kListPrefName, out).get());
- }
- // An incoming sync transaction should change the user value, not the managed
- // value.
- base::ListValue sync_value;
- sync_value.Append("http://crbug.com");
- syncer::SyncChangeList list;
- list.push_back(
- MakeRemoteChange(kListPrefName, sync_value, SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- const base::Value* managed_prefs_result;
- ASSERT_TRUE(managed_prefs_->GetValue(kListPrefName, &managed_prefs_result));
- EXPECT_EQ(managed_value, *managed_prefs_result);
- // Get should return the managed value, too.
- EXPECT_EQ(managed_value, *prefs_.Get(kListPrefName));
- // Verify the user pref value has the change.
- EXPECT_EQ(sync_value, *prefs_.GetUserPrefValue(kListPrefName));
- }
- TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedDictionaryValues) {
- {
- DictionaryPrefUpdate update(&prefs_, kDictPrefName);
- base::Value* dict_value = update.Get();
- dict_value->SetStringKey("my_key1", "my_value1");
- dict_value->SetStringKey("my_key3", "my_value3");
- }
- base::DictionaryValue remote_update;
- remote_update.Set("my_key2", std::make_unique<base::Value>("my_value2"));
- syncer::SyncDataList in;
- AddToRemoteDataList(kDictPrefName, remote_update, &in);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- base::DictionaryValue expected_dict;
- expected_dict.Set("my_key1", std::make_unique<base::Value>("my_value1"));
- expected_dict.Set("my_key2", std::make_unique<base::Value>("my_value2"));
- expected_dict.Set("my_key3", std::make_unique<base::Value>("my_value3"));
- std::unique_ptr<base::Value> value(FindValue(kDictPrefName, out));
- ASSERT_TRUE(value.get());
- EXPECT_EQ(*value, expected_dict);
- EXPECT_EQ(GetPreferenceValue(kDictPrefName), expected_dict);
- }
- // TODO(jamescook): In production all prefs are registered before the
- // PrefServiceSyncable is created. This test should do the same.
- TEST_F(PrefServiceSyncableMergeTest, KeepPriorityPreferencesSeparately) {
- const std::string pref_name = "testing.priority_pref";
- pref_registry_->RegisterStringPref(
- pref_name, "priority-default",
- user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
- syncer::SyncDataList in;
- // AddToRemoteDataList() produces sync data for non-priority prefs.
- AddToRemoteDataList(pref_name, base::Value("non-priority-value"), &in);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- EXPECT_THAT(GetPreferenceValue(pref_name).GetString(),
- Eq("priority-default"));
- }
- class ShouldNotBeNotifedObserver : public SyncedPrefObserver {
- public:
- ShouldNotBeNotifedObserver() = default;
- ~ShouldNotBeNotifedObserver() = default;
- void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
- ADD_FAILURE() << "Unexpected notification about a pref change with path: '"
- << path << "' and from_sync: " << from_sync;
- }
- };
- TEST_F(PrefServiceSyncableMergeTest, RegisterShouldClearTypeMismatchingData) {
- const std::string pref_name = "testing.pref";
- user_prefs_->SetString(pref_name, "string_value");
- ASSERT_TRUE(user_prefs_->GetValue(pref_name, nullptr));
- // Make sure no changes will be communicated to any synced pref listeners
- // (those listeners are typically only used for metrics but we still don't
- // want to inform them).
- ShouldNotBeNotifedObserver observer;
- prefs_.AddSyncedPrefObserver(pref_name, &observer);
- pref_registry_->RegisterListPref(
- pref_name, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
- EXPECT_TRUE(GetPreferenceValue(pref_name).GetListDeprecated().empty());
- EXPECT_FALSE(user_prefs_->GetValue(pref_name, nullptr));
- prefs_.RemoveSyncedPrefObserver(pref_name, &observer);
- }
- TEST_F(PrefServiceSyncableMergeTest, ShouldIgnoreUpdatesToNotSyncablePrefs) {
- const std::string pref_name = "testing.not_syncable_pref";
- pref_registry_->RegisterStringPref(pref_name, "default_value",
- PrefRegistry::NO_REGISTRATION_FLAGS);
- syncer::SyncDataList in;
- AddToRemoteDataList(pref_name, base::Value("remote_value"), &in);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(in, &out);
- EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
- syncer::SyncChangeList remote_changes;
- remote_changes.push_back(MakeRemoteChange(
- pref_name, base::Value("remote_value2"), SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
- // The pref isn't synced.
- EXPECT_THAT(pref_sync_service_->GetAllSyncDataForTesting(syncer::PREFERENCES),
- IsEmpty());
- EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
- }
- TEST_F(PrefServiceSyncableTest, FailModelAssociation) {
- syncer::SyncChangeList output;
- TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output);
- stub->FailNextProcessSyncChanges();
- absl::optional<syncer::ModelError> error =
- pref_sync_service_->MergeDataAndStartSyncing(
- syncer::PREFERENCES, syncer::SyncDataList(), base::WrapUnique(stub),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_TRUE(error.has_value());
- }
- TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithDefaultValue) {
- const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
- EXPECT_TRUE(pref->IsDefaultValue());
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- out.clear();
- base::Value expected(kExampleUrl0);
- GetPrefs()->Set(kStringPrefName, expected);
- std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
- ASSERT_TRUE(actual.get());
- EXPECT_EQ(expected, *actual);
- }
- TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithValue) {
- GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- out.clear();
- base::Value expected(kExampleUrl1);
- GetPrefs()->Set(kStringPrefName, expected);
- std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
- ASSERT_TRUE(actual.get());
- EXPECT_EQ(expected, *actual);
- }
- TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdate) {
- GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
- InitWithNoSyncData();
- base::Value expected(kExampleUrl1);
- syncer::SyncChangeList list;
- list.push_back(
- MakeRemoteChange(kStringPrefName, expected, SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- const base::Value& actual = GetPreferenceValue(kStringPrefName);
- EXPECT_EQ(expected, actual);
- }
- // Verifies that the implementation gracefully handles a remote update with the
- // wrong type. The local version should not get modified in these cases.
- TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdateTypeMismatch) {
- GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
- InitWithNoSyncData();
- base::Value remote_int_value(123);
- syncer::SyncChangeList remote_changes;
- remote_changes.push_back(MakeRemoteChange(kStringPrefName, remote_int_value,
- SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
- EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
- }
- TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionAdd) {
- InitWithNoSyncData();
- base::Value expected(kExampleUrl0);
- syncer::SyncChangeList list;
- list.push_back(
- MakeRemoteChange(kStringPrefName, expected, SyncChange::ACTION_ADD));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- const base::Value& actual = GetPreferenceValue(kStringPrefName);
- EXPECT_EQ(expected, actual);
- EXPECT_TRUE(pref_sync_service_->IsPrefSyncedForTesting(kStringPrefName));
- }
- TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeUnknownPreference) {
- InitWithNoSyncData();
- syncer::SyncChangeList list;
- base::Value expected(kExampleUrl0);
- list.push_back(MakeRemoteChange("unknown preference", expected,
- SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- // Nothing interesting happens on the client when it gets an update
- // of an unknown preference. We just should not crash.
- }
- TEST_F(PrefServiceSyncableTest, ManagedPreferences) {
- // Make the homepage preference managed.
- base::Value managed_value("http://example.com");
- prefs_.SetManagedPref(kStringPrefName, managed_value.Clone());
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- out.clear();
- // Changing the homepage preference should not sync anything.
- base::Value user_value("http://chromium..com");
- prefs_.SetUserPref(kStringPrefName, user_value.Clone());
- EXPECT_TRUE(out.empty());
- // An incoming sync transaction should change the user value, not the managed
- // value.
- base::Value sync_value("http://crbug.com");
- syncer::SyncChangeList list;
- list.push_back(
- MakeRemoteChange(kStringPrefName, sync_value, SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- EXPECT_EQ(managed_value, *prefs_.GetManagedPref(kStringPrefName));
- EXPECT_EQ(sync_value, *prefs_.GetUserPref(kStringPrefName));
- }
- TEST_F(PrefServiceSyncableTest, DynamicManagedPreferences) {
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- out.clear();
- base::Value initial_value("http://example.com/initial");
- GetPrefs()->Set(kStringPrefName, initial_value);
- std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
- ASSERT_TRUE(actual.get());
- EXPECT_EQ(initial_value, *actual);
- // Switch kHomePage to managed and set a different value.
- base::Value managed_value("http://example.com/managed");
- GetTestingPrefService()->SetManagedPref(kStringPrefName,
- managed_value.Clone());
- // The pref value should be the one dictated by policy.
- EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
- // Switch kHomePage back to unmanaged.
- GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
- // The original value should be picked up.
- EXPECT_EQ(initial_value, GetPreferenceValue(kStringPrefName));
- }
- TEST_F(PrefServiceSyncableTest, DynamicManagedPreferencesWithSyncChange) {
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- out.clear();
- base::Value initial_value("http://example.com/initial");
- GetPrefs()->Set(kStringPrefName, initial_value);
- std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
- EXPECT_EQ(initial_value, *actual);
- // Switch kHomePage to managed and set a different value.
- base::Value managed_value("http://example.com/managed");
- GetTestingPrefService()->SetManagedPref(kStringPrefName,
- managed_value.Clone());
- // Change the sync value.
- base::Value sync_value("http://example.com/sync");
- syncer::SyncChangeList list;
- list.push_back(
- MakeRemoteChange(kStringPrefName, sync_value, SyncChange::ACTION_UPDATE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- // The pref value should still be the one dictated by policy.
- EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
- // Switch kHomePage back to unmanaged.
- GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
- // Sync value should be picked up.
- EXPECT_EQ(sync_value, GetPreferenceValue(kStringPrefName));
- }
- TEST_F(PrefServiceSyncableTest, DynamicManagedDefaultPreferences) {
- const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
- EXPECT_TRUE(pref->IsDefaultValue());
- syncer::SyncChangeList out;
- InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
- EXPECT_TRUE(IsRegistered(kStringPrefName));
- EXPECT_TRUE(pref->IsDefaultValue());
- EXPECT_FALSE(FindValue(kStringPrefName, out).get());
- out.clear();
- // Switch kHomePage to managed and set a different value.
- base::Value managed_value("http://example.com/managed");
- GetTestingPrefService()->SetManagedPref(kStringPrefName,
- managed_value.Clone());
- // The pref value should be the one dictated by policy.
- EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
- EXPECT_FALSE(pref->IsDefaultValue());
- // There should be no synced value.
- EXPECT_FALSE(FindValue(kStringPrefName, out).get());
- // Switch kHomePage back to unmanaged.
- GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
- // The original value should be picked up.
- EXPECT_TRUE(pref->IsDefaultValue());
- // There should still be no synced value.
- EXPECT_FALSE(FindValue(kStringPrefName, out).get());
- }
- TEST_F(PrefServiceSyncableTest, DeletePreference) {
- prefs_.SetString(kStringPrefName, kExampleUrl0);
- const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
- EXPECT_FALSE(pref->IsDefaultValue());
- InitWithNoSyncData();
- auto null_value = std::make_unique<base::Value>();
- syncer::SyncChangeList list;
- list.push_back(MakeRemoteChange(kStringPrefName, *null_value,
- SyncChange::ACTION_DELETE));
- pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
- EXPECT_TRUE(pref->IsDefaultValue());
- }
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- // The Chrome OS tests exercise pref model association that happens in the
- // constructor of PrefServiceSyncable. The tests must register prefs first,
- // then create the PrefServiceSyncable object. The tests live in this file
- // because they share utility code with the cross-platform tests.
- class PrefServiceSyncableChromeOsTest : public testing::Test {
- public:
- PrefServiceSyncableChromeOsTest()
- : pref_registry_(base::MakeRefCounted<PrefRegistrySyncable>()),
- pref_notifier_(new PrefNotifierImpl),
- user_prefs_(base::MakeRefCounted<TestingPrefStore>()),
- standalone_browser_prefs_(base::MakeRefCounted<TestingPrefStore>()) {}
- void CreatePrefService() {
- // Register prefs of various types.
- pref_registry_->RegisterStringPref("unsynced_pref", std::string());
- pref_registry_->RegisterStringPref("browser_pref", std::string(),
- PrefRegistrySyncable::SYNCABLE_PREF);
- pref_registry_->RegisterStringPref(
- "browser_priority_pref", std::string(),
- PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
- pref_registry_->RegisterStringPref("os_pref", std::string(),
- PrefRegistrySyncable::SYNCABLE_OS_PREF);
- pref_registry_->RegisterStringPref(
- "os_priority_pref", std::string(),
- PrefRegistrySyncable::SYNCABLE_OS_PRIORITY_PREF);
- client_.SetIsDictPref(false);
- // Create the PrefServiceSyncable after prefs are registered, which is the
- // order used in production.
- prefs_ = std::make_unique<PrefServiceSyncable>(
- std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
- std::make_unique<PrefValueStore>(
- new TestingPrefStore, new TestingPrefStore, new TestingPrefStore,
- new TestingPrefStore, new TestingPrefStore, user_prefs_.get(),
- standalone_browser_prefs_.get(), pref_registry_->defaults().get(),
- pref_notifier_),
- user_prefs_, standalone_browser_prefs_, pref_registry_, &client_,
- /*read_error_callback=*/base::DoNothing(),
- /*async=*/false);
- }
- void InitSyncForType(ModelType type,
- syncer::SyncChangeList* output = nullptr) {
- syncer::SyncDataList empty_data;
- absl::optional<syncer::ModelError> error =
- prefs_->GetSyncableService(type)->MergeDataAndStartSyncing(
- type, empty_data, std::make_unique<TestSyncProcessorStub>(output),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_FALSE(error.has_value());
- }
- void InitSyncForAllTypes(syncer::SyncChangeList* output = nullptr) {
- for (ModelType type : kAllPreferenceModelTypes) {
- InitSyncForType(type, output);
- }
- }
- ModelTypeSet GetRegisteredModelTypes(const std::string& pref_name) {
- ModelTypeSet registered_types;
- for (ModelType type : kAllPreferenceModelTypes) {
- if (static_cast<PrefModelAssociator*>(prefs_->GetSyncableService(type))
- ->IsPrefRegistered(pref_name)) {
- registered_types.Put(type);
- }
- }
- return registered_types;
- }
- SyncData MakeRemoteSyncData(const std::string& name,
- const base::Value& value,
- syncer::ModelType model_type) {
- std::string serialized;
- JSONStringValueSerializer json(&serialized);
- EXPECT_TRUE(json.Serialize(value));
- sync_pb::EntitySpecifics entity;
- sync_pb::PreferenceSpecifics* pref =
- PrefModelAssociator::GetMutableSpecifics(model_type, &entity);
- pref->set_name(name);
- pref->set_value(serialized);
- return SyncData::CreateRemoteData(
- entity, syncer::ClientTagHash::FromUnhashed(model_type, name));
- }
- protected:
- base::test::ScopedFeatureList feature_list_;
- scoped_refptr<PrefRegistrySyncable> pref_registry_;
- PrefNotifierImpl* pref_notifier_; // Owned by |prefs_|.
- scoped_refptr<TestingPrefStore> user_prefs_;
- scoped_refptr<TestingPrefStore> standalone_browser_prefs_;
- TestPrefModelAssociatorClient client_;
- std::unique_ptr<PrefServiceSyncable> prefs_;
- };
- TEST_F(PrefServiceSyncableChromeOsTest,
- IsPrefRegistered_CategorizationDisabled) {
- feature_list_.InitAndDisableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- EXPECT_TRUE(GetRegisteredModelTypes("unsynced_pref").Empty());
- EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
- GetRegisteredModelTypes("browser_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
- GetRegisteredModelTypes("browser_priority_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
- GetRegisteredModelTypes("os_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
- GetRegisteredModelTypes("os_priority_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- IsPrefRegistered_CategorizationEnabled) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- EXPECT_TRUE(GetRegisteredModelTypes("unsynced_pref").Empty());
- EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
- GetRegisteredModelTypes("browser_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
- GetRegisteredModelTypes("browser_priority_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::OS_PREFERENCES),
- GetRegisteredModelTypes("os_pref"));
- EXPECT_EQ(ModelTypeSet(syncer::OS_PRIORITY_PREFERENCES),
- GetRegisteredModelTypes("os_priority_pref"));
- // The associator for PREFERENCES knows about OS prefs so that local updates
- // are synced back to old clients.
- auto* pref_associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::PREFERENCES));
- EXPECT_TRUE(pref_associator->IsLegacyModelTypePref("os_pref"));
- // The associator for PRIORITY_PREFERENCES knows about OS priority prefs so
- // that local updates are synced back to old clients.
- auto* priority_associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::PRIORITY_PREFERENCES));
- EXPECT_TRUE(priority_associator->IsLegacyModelTypePref("os_priority_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest, IsSyncing) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForType(syncer::PREFERENCES);
- EXPECT_TRUE(prefs_->IsSyncing());
- EXPECT_FALSE(prefs_->IsPrioritySyncing());
- EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
- EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
- }
- TEST_F(PrefServiceSyncableChromeOsTest, IsPrioritySyncing) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForType(syncer::PRIORITY_PREFERENCES);
- EXPECT_FALSE(prefs_->IsSyncing());
- EXPECT_TRUE(prefs_->IsPrioritySyncing());
- EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
- EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
- }
- TEST_F(PrefServiceSyncableChromeOsTest, AreOsPrefsSyncing) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForType(syncer::OS_PREFERENCES);
- EXPECT_FALSE(prefs_->IsSyncing());
- EXPECT_FALSE(prefs_->IsPrioritySyncing());
- EXPECT_TRUE(prefs_->AreOsPrefsSyncing());
- EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
- }
- TEST_F(PrefServiceSyncableChromeOsTest, AreOsPriorityPrefsSyncing) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForType(syncer::OS_PRIORITY_PREFERENCES);
- EXPECT_FALSE(prefs_->IsSyncing());
- EXPECT_FALSE(prefs_->IsPrioritySyncing());
- EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
- EXPECT_TRUE(prefs_->AreOsPriorityPrefsSyncing());
- }
- TEST_F(PrefServiceSyncableChromeOsTest, IsPrefSynced_OsPref) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForAllTypes();
- auto* associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::OS_PREFERENCES));
- EXPECT_FALSE(associator->IsPrefSyncedForTesting("os_pref"));
- syncer::SyncChangeList list;
- list.push_back(MakeRemoteChange("os_pref", base::Value("value"),
- SyncChange::ACTION_ADD,
- syncer::OS_PREFERENCES));
- associator->ProcessSyncChanges(FROM_HERE, list);
- EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest, IsPrefSynced_OsPriorityPref) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForAllTypes();
- auto* associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::OS_PRIORITY_PREFERENCES));
- EXPECT_FALSE(associator->IsPrefSyncedForTesting("os_priority_pref"));
- syncer::SyncChangeList list;
- list.push_back(MakeRemoteChange("os_priority_pref", base::Value("value"),
- SyncChange::ACTION_ADD,
- syncer::OS_PRIORITY_PREFERENCES));
- associator->ProcessSyncChanges(FROM_HERE, list);
- EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_priority_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_OsPref) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForAllTypes();
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- prefs_->SetString("os_pref", "value");
- EXPECT_EQ("os_pref", observer.last_pref_);
- EXPECT_EQ(1, observer.changed_count_);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_OsPriorityPref) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForAllTypes();
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_priority_pref", &observer);
- prefs_->SetString("os_priority_pref", "value");
- EXPECT_EQ("os_priority_pref", observer.last_pref_);
- EXPECT_EQ(1, observer.changed_count_);
- prefs_->RemoveSyncedPrefObserver("os_priority_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- OsPrefChangeSyncedAsBrowserPrefChange_CategorizationDisabled) {
- feature_list_.InitAndDisableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- // Set a non-default value.
- prefs_->SetString("os_pref", "new_value");
- // Start syncing.
- syncer::SyncChangeList output;
- InitSyncForAllTypes(&output);
- ASSERT_EQ(1u, output.size());
- // The OS pref is treated like a browser pref.
- EXPECT_EQ(syncer::PREFERENCES, output[0].sync_data().GetDataType());
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- OsPrefChangeSyncedAsOsPrefChange_CategorizationEnabled) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- // Set a non-default value.
- prefs_->SetString("os_pref", "new_value");
- // Start syncing.
- syncer::SyncChangeList output;
- InitSyncForAllTypes(&output);
- ASSERT_EQ(1u, output.size());
- // The OS pref is treated like an OS pref.
- EXPECT_EQ(syncer::OS_PREFERENCES, output[0].sync_data().GetDataType());
- // Future changes will be synced back to browser preferences as well.
- auto* associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::PREFERENCES));
- EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- OsPrefChangeMakesSyncChangeForOldClients_CategorizationEnabled_Update) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- syncer::SyncChangeList changes;
- InitSyncForAllTypes(&changes);
- EXPECT_THAT(changes, IsEmpty());
- // Make a local change.
- prefs_->SetString("os_pref", "new_value");
- // Sync changes are made for the legacy ModelType::PREFERENCES (so old clients
- // will get updates) and for the current ModelType::OS_PREFERENCES (so new
- // clients will get updates).
- EXPECT_THAT(changes,
- UnorderedElementsAre(MatchesModelType(syncer::PREFERENCES),
- MatchesModelType(syncer::OS_PREFERENCES)));
- // Future changes will be synced back to browser preferences as well.
- auto* associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::PREFERENCES));
- EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- UpdatesFromOldClientsAreIgnored_Startup) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- // Simulate an old client that has "os_pref" registered as SYNCABLE_PREF
- // instead of SYNCABLE_OS_PREF.
- syncer::SyncDataList list;
- list.push_back(CreateRemoteSyncData("os_pref", base::Value("new_value")));
- // Simulate the first sync at startup of the legacy browser prefs ModelType.
- auto* browser_associator = static_cast<PrefModelAssociator*>(
- prefs_->GetSyncableService(syncer::PREFERENCES));
- syncer::SyncChangeList outgoing_changes;
- browser_associator->MergeDataAndStartSyncing(
- syncer::PREFERENCES, list,
- std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- // No outgoing changes were triggered.
- EXPECT_TRUE(outgoing_changes.empty());
- // The value from the old client was not applied.
- EXPECT_NE("new_value", prefs_->GetString("os_pref"));
- // The pref is not considered to be syncing, because it still has its default
- // value.
- EXPECT_FALSE(browser_associator->IsPrefSyncedForTesting("os_pref"));
- // Observers were not notified of changes.
- EXPECT_EQ(0, observer.changed_count_);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- UpdatesFromOldClientsAreIgnored_Update) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- InitSyncForAllTypes();
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- syncer::SyncChangeList list;
- // Simulate an old client that has "os_pref" registered as SYNCABLE_PREF
- // instead of SYNCABLE_OS_PREF.
- list.push_back(MakeRemoteChange("os_pref", base::Value("new_value"),
- SyncChange::ACTION_ADD, syncer::PREFERENCES));
- // Simulate a sync update after startup.
- prefs_->GetSyncableService(syncer::PREFERENCES)
- ->ProcessSyncChanges(FROM_HERE, list);
- // Update was not applied.
- EXPECT_NE("new_value", prefs_->GetString("os_pref"));
- // Observers were not notified of changes.
- EXPECT_EQ(0, observer.changed_count_);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- SyncedPrefObserver_OsPrefIsChangedFromSync) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- prefs_->SetString("os_pref", "default_value");
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- TestPrefServiceSyncableObserver pref_service_sync_observer;
- pref_service_sync_observer.SetSyncedPrefObserver(&observer);
- prefs_->AddObserver(&pref_service_sync_observer);
- // Simulate that "os_pref" is registered as SYNCABLE_PREF
- syncer::SyncDataList list;
- list.push_back(MakeRemoteSyncData("os_pref", base::Value("new_value"),
- syncer::OS_PREFERENCES));
- // Simulate the first sync at startup.
- syncer::SyncChangeList outgoing_changes;
- prefs_->GetSyncableService(syncer::OS_PREFERENCES)
- ->MergeDataAndStartSyncing(
- syncer::OS_PREFERENCES, list,
- std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_EQ("os_pref", observer.synced_pref_);
- EXPECT_EQ(1, observer.sync_started_count_);
- EXPECT_TRUE(pref_service_sync_observer.is_syncing_changed());
- prefs_->RemoveObserver(&pref_service_sync_observer);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest,
- SyncedPrefObserver_OsPrefIsNotChangedFromSync) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- prefs_->SetString("os_pref", "default_value");
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- TestPrefServiceSyncableObserver pref_service_sync_observer;
- pref_service_sync_observer.SetSyncedPrefObserver(&observer);
- prefs_->AddObserver(&pref_service_sync_observer);
- // Simulate that "os_pref" is registered as SYNCABLE_PREF
- syncer::SyncDataList list;
- list.push_back(MakeRemoteSyncData("os_pref", base::Value("new_value"),
- syncer::OS_PREFERENCES));
- // Simulate the first sync at startup.
- syncer::SyncChangeList outgoing_changes;
- prefs_->GetSyncableService(syncer::OS_PREFERENCES)
- ->MergeDataAndStartSyncing(
- syncer::OS_PREFERENCES, list,
- std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_EQ("os_pref", observer.synced_pref_);
- EXPECT_EQ(1, observer.sync_started_count_);
- EXPECT_TRUE(pref_service_sync_observer.is_syncing_changed());
- prefs_->RemoveObserver(&pref_service_sync_observer);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_EmptyCloud) {
- feature_list_.InitAndEnableFeature(
- chromeos::features::kSyncSettingsCategorization);
- CreatePrefService();
- prefs_->SetString("os_pref", "new_value");
- TestSyncedPrefObserver observer;
- prefs_->AddSyncedPrefObserver("os_pref", &observer);
- // Simulate the first sync at startup.
- syncer::SyncChangeList outgoing_changes;
- prefs_->GetSyncableService(syncer::OS_PREFERENCES)
- ->MergeDataAndStartSyncing(
- syncer::OS_PREFERENCES, syncer::SyncDataList(),
- std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
- std::make_unique<syncer::SyncErrorFactoryMock>());
- EXPECT_EQ("", observer.synced_pref_);
- EXPECT_EQ(0, observer.sync_started_count_);
- prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
- }
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- } // namespace
- } // namespace sync_preferences
|