pref_service_syncable_unittest.cc 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. // Copyright 2014 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. #include "components/sync_preferences/pref_service_syncable.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/json/json_reader.h"
  10. #include "base/json/json_string_value_serializer.h"
  11. #include "base/json/json_writer.h"
  12. #include "base/memory/ptr_util.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/strings/utf_string_conversions.h"
  15. #include "build/chromeos_buildflags.h"
  16. #include "components/pref_registry/pref_registry_syncable.h"
  17. #include "components/prefs/pref_notifier_impl.h"
  18. #include "components/prefs/scoped_user_pref_update.h"
  19. #include "components/prefs/testing_pref_store.h"
  20. #include "components/sync/base/client_tag_hash.h"
  21. #include "components/sync/base/model_type.h"
  22. #include "components/sync/model/sync_change.h"
  23. #include "components/sync/model/sync_change_processor.h"
  24. #include "components/sync/model/sync_data.h"
  25. #include "components/sync/model/syncable_service.h"
  26. #include "components/sync/protocol/entity_specifics.pb.h"
  27. #include "components/sync/protocol/preference_specifics.pb.h"
  28. #include "components/sync/test/sync_error_factory_mock.h"
  29. #include "components/sync_preferences/pref_model_associator.h"
  30. #include "components/sync_preferences/pref_model_associator_client.h"
  31. #include "components/sync_preferences/pref_service_syncable_observer.h"
  32. #include "components/sync_preferences/synced_pref_observer.h"
  33. #include "components/sync_preferences/testing_pref_service_syncable.h"
  34. #include "testing/gtest/include/gtest/gtest.h"
  35. #if BUILDFLAG(IS_CHROMEOS_ASH)
  36. #include "ash/constants/ash_features.h"
  37. #include "base/test/scoped_feature_list.h"
  38. #include "testing/gmock/include/gmock/gmock-matchers.h"
  39. #endif
  40. using syncer::ModelType;
  41. using syncer::ModelTypeSet;
  42. using syncer::SyncChange;
  43. using syncer::SyncData;
  44. using testing::Eq;
  45. using testing::IsEmpty;
  46. using testing::Matches;
  47. using testing::NotNull;
  48. using testing::UnorderedElementsAre;
  49. using user_prefs::PrefRegistrySyncable;
  50. namespace sync_preferences {
  51. namespace {
  52. const char kExampleUrl0[] = "http://example.com/0";
  53. const char kExampleUrl1[] = "http://example.com/1";
  54. const char kExampleUrl2[] = "http://example.com/2";
  55. const char kStringPrefName[] = "string_pref_name";
  56. const char kListPrefName[] = "list_pref_name";
  57. const char kDictPrefName[] = "dict_pref_name";
  58. const char kUnsyncedPreferenceName[] = "nonsense_pref_name";
  59. const char kUnsyncedPreferenceDefaultValue[] = "default";
  60. const char kDefaultCharsetPrefName[] = "default_charset";
  61. const char kNonDefaultCharsetValue[] = "foo";
  62. const char kDefaultCharsetValue[] = "utf-8";
  63. #if BUILDFLAG(IS_CHROMEOS_ASH)
  64. constexpr ModelTypeSet kAllPreferenceModelTypes(
  65. syncer::PREFERENCES,
  66. syncer::PRIORITY_PREFERENCES,
  67. syncer::OS_PREFERENCES,
  68. syncer::OS_PRIORITY_PREFERENCES);
  69. MATCHER_P(MatchesModelType, model_type, "") {
  70. const syncer::SyncChange& sync_change = arg;
  71. return Matches(model_type)(sync_change.sync_data().GetDataType());
  72. }
  73. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  74. class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
  75. public:
  76. explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
  77. : output_(output) {}
  78. absl::optional<syncer::ModelError> ProcessSyncChanges(
  79. const base::Location& from_here,
  80. const syncer::SyncChangeList& change_list) override {
  81. if (output_) {
  82. output_->insert(output_->end(), change_list.begin(), change_list.end());
  83. }
  84. if (fail_next_) {
  85. fail_next_ = false;
  86. return syncer::ModelError(FROM_HERE, "Error");
  87. }
  88. return absl::nullopt;
  89. }
  90. void FailNextProcessSyncChanges() { fail_next_ = true; }
  91. private:
  92. raw_ptr<syncer::SyncChangeList> output_;
  93. bool fail_next_ = false;
  94. };
  95. class TestSyncedPrefObserver : public SyncedPrefObserver {
  96. public:
  97. TestSyncedPrefObserver() = default;
  98. ~TestSyncedPrefObserver() = default;
  99. void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
  100. last_pref_ = path;
  101. changed_count_++;
  102. }
  103. void OnStartedSyncing(const std::string& path) override {
  104. synced_pref_ = path;
  105. sync_started_count_++;
  106. }
  107. std::string last_pref_;
  108. int changed_count_ = 0;
  109. std::string synced_pref_;
  110. int sync_started_count_ = 0;
  111. };
  112. class TestPrefServiceSyncableObserver : public PrefServiceSyncableObserver {
  113. public:
  114. TestPrefServiceSyncableObserver() = default;
  115. ~TestPrefServiceSyncableObserver() override = default;
  116. void OnIsSyncingChanged() override {
  117. if (sync_pref_observer_ && sync_pref_observer_->sync_started_count_ > 0) {
  118. is_syncing_changed_ = true;
  119. }
  120. }
  121. void SetSyncedPrefObserver(const TestSyncedPrefObserver* sync_pref_observer) {
  122. sync_pref_observer_ = sync_pref_observer;
  123. }
  124. bool is_syncing_changed() { return is_syncing_changed_; }
  125. private:
  126. bool is_syncing_changed_ = false;
  127. raw_ptr<const TestSyncedPrefObserver> sync_pref_observer_ = nullptr;
  128. };
  129. syncer::SyncChange MakeRemoteChange(const std::string& name,
  130. const base::Value& value,
  131. SyncChange::SyncChangeType change_type,
  132. syncer::ModelType model_type) {
  133. std::string serialized;
  134. JSONStringValueSerializer json(&serialized);
  135. bool success = json.Serialize(value);
  136. DCHECK(success);
  137. sync_pb::EntitySpecifics entity;
  138. sync_pb::PreferenceSpecifics* pref =
  139. PrefModelAssociator::GetMutableSpecifics(model_type, &entity);
  140. pref->set_name(name);
  141. pref->set_value(serialized);
  142. return syncer::SyncChange(
  143. FROM_HERE, change_type,
  144. syncer::SyncData::CreateRemoteData(
  145. entity, syncer::ClientTagHash::FromUnhashed(model_type, name)));
  146. }
  147. // Creates a SyncChange for model type |PREFERENCES|.
  148. syncer::SyncChange MakeRemoteChange(const std::string& name,
  149. const base::Value& value,
  150. SyncChange::SyncChangeType type) {
  151. return MakeRemoteChange(name, value, type, syncer::ModelType::PREFERENCES);
  152. }
  153. // Creates SyncData for a remote pref change.
  154. SyncData CreateRemoteSyncData(const std::string& name,
  155. const base::Value& value) {
  156. std::string serialized;
  157. JSONStringValueSerializer json(&serialized);
  158. EXPECT_TRUE(json.Serialize(value));
  159. sync_pb::EntitySpecifics one;
  160. sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
  161. pref_one->set_name(name);
  162. pref_one->set_value(serialized);
  163. return SyncData::CreateRemoteData(
  164. one, syncer::ClientTagHash::FromUnhashed(syncer::ModelType::PREFERENCES,
  165. name));
  166. }
  167. class PrefServiceSyncableTest : public testing::Test {
  168. public:
  169. PrefServiceSyncableTest() = default;
  170. void SetUp() override {
  171. prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName,
  172. kUnsyncedPreferenceDefaultValue);
  173. prefs_.registry()->RegisterStringPref(
  174. kStringPrefName, std::string(),
  175. user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  176. prefs_.registry()->RegisterListPref(
  177. kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  178. prefs_.registry()->RegisterStringPref(
  179. kDefaultCharsetPrefName, kDefaultCharsetValue,
  180. user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  181. pref_sync_service_ = static_cast<PrefModelAssociator*>(
  182. prefs_.GetSyncableService(syncer::PREFERENCES));
  183. ASSERT_TRUE(pref_sync_service_);
  184. }
  185. void AddToRemoteDataList(const std::string& name,
  186. const base::Value& value,
  187. syncer::SyncDataList* out) {
  188. out->push_back(CreateRemoteSyncData(name, value));
  189. }
  190. void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
  191. syncer::SyncChangeList* output) {
  192. absl::optional<syncer::ModelError> error =
  193. pref_sync_service_->MergeDataAndStartSyncing(
  194. syncer::PREFERENCES, initial_data,
  195. std::make_unique<TestSyncProcessorStub>(output),
  196. std::make_unique<syncer::SyncErrorFactoryMock>());
  197. EXPECT_FALSE(error.has_value());
  198. }
  199. void InitWithNoSyncData() {
  200. InitWithSyncDataTakeOutput(syncer::SyncDataList(), nullptr);
  201. }
  202. const base::Value& GetPreferenceValue(const std::string& name) {
  203. const PrefService::Preference* preference =
  204. prefs_.FindPreference(name.c_str());
  205. return *preference->GetValue();
  206. }
  207. std::unique_ptr<base::Value> FindValue(const std::string& name,
  208. const syncer::SyncChangeList& list) {
  209. auto it = list.begin();
  210. for (; it != list.end(); ++it) {
  211. if (it->sync_data().GetClientTagHash() ==
  212. syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)) {
  213. return base::JSONReader::ReadDeprecated(
  214. it->sync_data().GetSpecifics().preference().value());
  215. }
  216. }
  217. return nullptr;
  218. }
  219. bool IsRegistered(const std::string& pref_name) {
  220. return pref_sync_service_->IsPrefRegistered(pref_name.c_str());
  221. }
  222. PrefService* GetPrefs() { return &prefs_; }
  223. TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; }
  224. protected:
  225. TestingPrefServiceSyncable prefs_;
  226. raw_ptr<PrefModelAssociator> pref_sync_service_ = nullptr;
  227. };
  228. TEST_F(PrefServiceSyncableTest, CreatePrefSyncData) {
  229. prefs_.SetString(kStringPrefName, kExampleUrl0);
  230. const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
  231. syncer::SyncData sync_data;
  232. EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(
  233. pref->name(), *pref->GetValue(), &sync_data));
  234. EXPECT_EQ(
  235. syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, kStringPrefName),
  236. sync_data.GetClientTagHash());
  237. const sync_pb::PreferenceSpecifics& specifics(
  238. sync_data.GetSpecifics().preference());
  239. EXPECT_EQ(std::string(kStringPrefName), specifics.name());
  240. std::unique_ptr<base::Value> value =
  241. base::JSONReader::ReadDeprecated(specifics.value());
  242. EXPECT_EQ(*pref->GetValue(), *value);
  243. }
  244. TEST_F(PrefServiceSyncableTest, ModelAssociationDoNotSyncDefaults) {
  245. const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
  246. EXPECT_TRUE(pref->IsDefaultValue());
  247. syncer::SyncChangeList out;
  248. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  249. EXPECT_TRUE(IsRegistered(kStringPrefName));
  250. EXPECT_TRUE(pref->IsDefaultValue());
  251. EXPECT_FALSE(FindValue(kStringPrefName, out).get());
  252. }
  253. TEST_F(PrefServiceSyncableTest, ModelAssociationEmptyCloud) {
  254. prefs_.SetString(kStringPrefName, kExampleUrl0);
  255. {
  256. ListPrefUpdate update(GetPrefs(), kListPrefName);
  257. base::Value* url_list = update.Get();
  258. url_list->Append(kExampleUrl0);
  259. url_list->Append(kExampleUrl1);
  260. }
  261. syncer::SyncChangeList out;
  262. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  263. std::unique_ptr<base::Value> value(FindValue(kStringPrefName, out));
  264. ASSERT_TRUE(value.get());
  265. EXPECT_EQ(GetPreferenceValue(kStringPrefName), *value);
  266. value = FindValue(kListPrefName, out);
  267. ASSERT_TRUE(value.get());
  268. EXPECT_EQ(GetPreferenceValue(kListPrefName), *value);
  269. }
  270. TEST_F(PrefServiceSyncableTest, ModelAssociationCloudHasData) {
  271. prefs_.SetString(kStringPrefName, kExampleUrl0);
  272. {
  273. ListPrefUpdate update(GetPrefs(), kListPrefName);
  274. base::Value* url_list = update.Get();
  275. url_list->Append(kExampleUrl0);
  276. }
  277. syncer::SyncDataList in;
  278. syncer::SyncChangeList out;
  279. AddToRemoteDataList(kStringPrefName, base::Value(kExampleUrl1), &in);
  280. base::ListValue urls_to_restore;
  281. urls_to_restore.Append(kExampleUrl1);
  282. AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
  283. AddToRemoteDataList(kDefaultCharsetPrefName,
  284. base::Value(kNonDefaultCharsetValue), &in);
  285. InitWithSyncDataTakeOutput(in, &out);
  286. ASSERT_FALSE(FindValue(kStringPrefName, out).get());
  287. ASSERT_FALSE(FindValue(kDefaultCharsetPrefName, out).get());
  288. EXPECT_EQ(kExampleUrl1, prefs_.GetString(kStringPrefName));
  289. // No associator client is registered, so lists and dictionaries should not
  290. // get merged (remote write wins).
  291. auto expected_urls = std::make_unique<base::ListValue>();
  292. expected_urls->Append(kExampleUrl1);
  293. EXPECT_FALSE(FindValue(kListPrefName, out));
  294. EXPECT_EQ(GetPreferenceValue(kListPrefName), *expected_urls);
  295. EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName));
  296. }
  297. // Verifies that the implementation gracefully handles an initial remote sync
  298. // data of wrong type. The local version should not get modified in these cases.
  299. TEST_F(PrefServiceSyncableTest, ModelAssociationWithDataTypeMismatch) {
  300. prefs_.SetString(kStringPrefName, kExampleUrl0);
  301. syncer::SyncDataList in;
  302. base::Value remote_int_value(123);
  303. AddToRemoteDataList(kStringPrefName, remote_int_value, &in);
  304. syncer::SyncChangeList out;
  305. InitWithSyncDataTakeOutput(in, &out);
  306. EXPECT_THAT(out, IsEmpty());
  307. EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
  308. }
  309. class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
  310. public:
  311. TestPrefModelAssociatorClient() = default;
  312. TestPrefModelAssociatorClient(const TestPrefModelAssociatorClient&) = delete;
  313. TestPrefModelAssociatorClient& operator=(
  314. const TestPrefModelAssociatorClient&) = delete;
  315. ~TestPrefModelAssociatorClient() override = default;
  316. // PrefModelAssociatorClient implementation.
  317. bool IsMergeableListPreference(const std::string& pref_name) const override {
  318. return pref_name == kListPrefName;
  319. }
  320. bool IsMergeableDictionaryPreference(
  321. const std::string& pref_name) const override {
  322. return is_dict_pref_;
  323. }
  324. base::Value MaybeMergePreferenceValues(
  325. const std::string& pref_name,
  326. const base::Value& local_value,
  327. const base::Value& server_value) const override {
  328. return base::Value();
  329. }
  330. void SetIsDictPref(bool is_dict_pref) { is_dict_pref_ = is_dict_pref; }
  331. private:
  332. bool is_dict_pref_ = true;
  333. };
  334. class PrefServiceSyncableMergeTest : public testing::Test {
  335. public:
  336. PrefServiceSyncableMergeTest()
  337. : prefs_(
  338. std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
  339. std::make_unique<PrefValueStore>(managed_prefs_.get(),
  340. new TestingPrefStore,
  341. new TestingPrefStore,
  342. new TestingPrefStore,
  343. new TestingPrefStore,
  344. user_prefs_.get(),
  345. standalone_browser_prefs_.get(),
  346. pref_registry_->defaults().get(),
  347. pref_notifier_),
  348. user_prefs_,
  349. standalone_browser_prefs_,
  350. pref_registry_,
  351. &client_,
  352. /*read_error_callback=*/base::DoNothing(),
  353. /*async=*/false) {}
  354. void SetUp() override {
  355. pref_registry_->RegisterStringPref(kUnsyncedPreferenceName,
  356. kUnsyncedPreferenceDefaultValue);
  357. pref_registry_->RegisterStringPref(
  358. kStringPrefName, std::string(),
  359. user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  360. pref_registry_->RegisterListPref(
  361. kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  362. pref_registry_->RegisterDictionaryPref(
  363. kDictPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  364. pref_registry_->RegisterStringPref(
  365. kDefaultCharsetPrefName, kDefaultCharsetValue,
  366. user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  367. pref_sync_service_ = static_cast<PrefModelAssociator*>(
  368. prefs_.GetSyncableService(syncer::PREFERENCES));
  369. ASSERT_THAT(pref_sync_service_, NotNull());
  370. }
  371. syncer::SyncChange MakeRemoteChange(const std::string& name,
  372. const base::Value& value,
  373. SyncChange::SyncChangeType type) {
  374. std::string serialized;
  375. JSONStringValueSerializer json(&serialized);
  376. CHECK(json.Serialize(value));
  377. sync_pb::EntitySpecifics entity;
  378. sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference();
  379. pref_one->set_name(name);
  380. pref_one->set_value(serialized);
  381. return syncer::SyncChange(FROM_HERE, type,
  382. syncer::SyncData::CreateRemoteData(
  383. entity, syncer::ClientTagHash::FromUnhashed(
  384. syncer::PREFERENCES, name)));
  385. }
  386. void AddToRemoteDataList(const std::string& name,
  387. const base::Value& value,
  388. syncer::SyncDataList* out) {
  389. std::string serialized;
  390. JSONStringValueSerializer json(&serialized);
  391. ASSERT_TRUE(json.Serialize(value));
  392. sync_pb::EntitySpecifics one;
  393. sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
  394. pref_one->set_name(name);
  395. pref_one->set_value(serialized);
  396. out->push_back(SyncData::CreateRemoteData(
  397. one, syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)));
  398. }
  399. void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
  400. syncer::SyncChangeList* output) {
  401. absl::optional<syncer::ModelError> error =
  402. pref_sync_service_->MergeDataAndStartSyncing(
  403. syncer::PREFERENCES, initial_data,
  404. std::make_unique<TestSyncProcessorStub>(output),
  405. std::make_unique<syncer::SyncErrorFactoryMock>());
  406. EXPECT_FALSE(error.has_value());
  407. }
  408. const base::Value& GetPreferenceValue(const std::string& name) {
  409. const PrefService::Preference* preference =
  410. prefs_.FindPreference(name.c_str());
  411. return *preference->GetValue();
  412. }
  413. std::unique_ptr<base::Value> FindValue(const std::string& name,
  414. const syncer::SyncChangeList& list) {
  415. auto it = list.begin();
  416. for (; it != list.end(); ++it) {
  417. if (it->sync_data().GetClientTagHash() ==
  418. syncer::ClientTagHash::FromUnhashed(syncer::PREFERENCES, name)) {
  419. return base::JSONReader::ReadDeprecated(
  420. it->sync_data().GetSpecifics().preference().value());
  421. }
  422. }
  423. return nullptr;
  424. }
  425. protected:
  426. scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_ =
  427. base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
  428. // Owned by prefs_;
  429. const raw_ptr<PrefNotifierImpl> pref_notifier_ = new PrefNotifierImpl;
  430. scoped_refptr<TestingPrefStore> managed_prefs_ =
  431. base::MakeRefCounted<TestingPrefStore>();
  432. scoped_refptr<TestingPrefStore> user_prefs_ =
  433. base::MakeRefCounted<TestingPrefStore>();
  434. scoped_refptr<TestingPrefStore> standalone_browser_prefs_ =
  435. base::MakeRefCounted<TestingPrefStore>();
  436. TestPrefModelAssociatorClient client_;
  437. PrefServiceSyncable prefs_;
  438. raw_ptr<PrefModelAssociator> pref_sync_service_ = nullptr;
  439. };
  440. TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedListValues) {
  441. {
  442. ListPrefUpdate update(&prefs_, kListPrefName);
  443. base::Value* url_list = update.Get();
  444. url_list->Append(kExampleUrl0);
  445. url_list->Append(kExampleUrl1);
  446. }
  447. base::ListValue urls_to_restore;
  448. urls_to_restore.Append(kExampleUrl1);
  449. urls_to_restore.Append(kExampleUrl2);
  450. syncer::SyncDataList in;
  451. AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
  452. syncer::SyncChangeList out;
  453. InitWithSyncDataTakeOutput(in, &out);
  454. std::unique_ptr<base::ListValue> expected_urls(new base::ListValue);
  455. expected_urls->Append(kExampleUrl1);
  456. expected_urls->Append(kExampleUrl2);
  457. expected_urls->Append(kExampleUrl0);
  458. std::unique_ptr<base::Value> value(FindValue(kListPrefName, out));
  459. ASSERT_TRUE(value.get());
  460. EXPECT_EQ(*value, *expected_urls) << *value;
  461. EXPECT_EQ(GetPreferenceValue(kListPrefName), *expected_urls);
  462. }
  463. // List preferences have special handling at association time due to our ability
  464. // to merge the local and sync value. Make sure the merge logic doesn't merge
  465. // managed preferences.
  466. TEST_F(PrefServiceSyncableMergeTest, ManagedListPreferences) {
  467. // Make the list of urls to restore on startup managed.
  468. base::Value managed_value(base::Value::Type::LIST);
  469. managed_value.Append(kExampleUrl0);
  470. managed_value.Append(kExampleUrl1);
  471. managed_prefs_->SetValue(kListPrefName,
  472. base::Value::ToUniquePtrValue(managed_value.Clone()),
  473. WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  474. // Set a cloud version.
  475. syncer::SyncDataList in;
  476. base::ListValue urls_to_restore;
  477. urls_to_restore.Append(kExampleUrl1);
  478. urls_to_restore.Append(kExampleUrl2);
  479. AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
  480. // Start sync and verify the synced value didn't get merged.
  481. {
  482. syncer::SyncChangeList out;
  483. InitWithSyncDataTakeOutput(in, &out);
  484. EXPECT_FALSE(FindValue(kListPrefName, out).get());
  485. }
  486. // Changing the user's urls to restore on startup pref should not sync
  487. // anything.
  488. {
  489. syncer::SyncChangeList out;
  490. base::ListValue user_value;
  491. user_value.Append("http://chromium.org");
  492. prefs_.Set(kListPrefName, user_value);
  493. EXPECT_FALSE(FindValue(kListPrefName, out).get());
  494. }
  495. // An incoming sync transaction should change the user value, not the managed
  496. // value.
  497. base::ListValue sync_value;
  498. sync_value.Append("http://crbug.com");
  499. syncer::SyncChangeList list;
  500. list.push_back(
  501. MakeRemoteChange(kListPrefName, sync_value, SyncChange::ACTION_UPDATE));
  502. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  503. const base::Value* managed_prefs_result;
  504. ASSERT_TRUE(managed_prefs_->GetValue(kListPrefName, &managed_prefs_result));
  505. EXPECT_EQ(managed_value, *managed_prefs_result);
  506. // Get should return the managed value, too.
  507. EXPECT_EQ(managed_value, *prefs_.Get(kListPrefName));
  508. // Verify the user pref value has the change.
  509. EXPECT_EQ(sync_value, *prefs_.GetUserPrefValue(kListPrefName));
  510. }
  511. TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedDictionaryValues) {
  512. {
  513. DictionaryPrefUpdate update(&prefs_, kDictPrefName);
  514. base::Value* dict_value = update.Get();
  515. dict_value->SetStringKey("my_key1", "my_value1");
  516. dict_value->SetStringKey("my_key3", "my_value3");
  517. }
  518. base::DictionaryValue remote_update;
  519. remote_update.Set("my_key2", std::make_unique<base::Value>("my_value2"));
  520. syncer::SyncDataList in;
  521. AddToRemoteDataList(kDictPrefName, remote_update, &in);
  522. syncer::SyncChangeList out;
  523. InitWithSyncDataTakeOutput(in, &out);
  524. base::DictionaryValue expected_dict;
  525. expected_dict.Set("my_key1", std::make_unique<base::Value>("my_value1"));
  526. expected_dict.Set("my_key2", std::make_unique<base::Value>("my_value2"));
  527. expected_dict.Set("my_key3", std::make_unique<base::Value>("my_value3"));
  528. std::unique_ptr<base::Value> value(FindValue(kDictPrefName, out));
  529. ASSERT_TRUE(value.get());
  530. EXPECT_EQ(*value, expected_dict);
  531. EXPECT_EQ(GetPreferenceValue(kDictPrefName), expected_dict);
  532. }
  533. // TODO(jamescook): In production all prefs are registered before the
  534. // PrefServiceSyncable is created. This test should do the same.
  535. TEST_F(PrefServiceSyncableMergeTest, KeepPriorityPreferencesSeparately) {
  536. const std::string pref_name = "testing.priority_pref";
  537. pref_registry_->RegisterStringPref(
  538. pref_name, "priority-default",
  539. user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
  540. syncer::SyncDataList in;
  541. // AddToRemoteDataList() produces sync data for non-priority prefs.
  542. AddToRemoteDataList(pref_name, base::Value("non-priority-value"), &in);
  543. syncer::SyncChangeList out;
  544. InitWithSyncDataTakeOutput(in, &out);
  545. EXPECT_THAT(GetPreferenceValue(pref_name).GetString(),
  546. Eq("priority-default"));
  547. }
  548. class ShouldNotBeNotifedObserver : public SyncedPrefObserver {
  549. public:
  550. ShouldNotBeNotifedObserver() = default;
  551. ~ShouldNotBeNotifedObserver() = default;
  552. void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
  553. ADD_FAILURE() << "Unexpected notification about a pref change with path: '"
  554. << path << "' and from_sync: " << from_sync;
  555. }
  556. };
  557. TEST_F(PrefServiceSyncableMergeTest, RegisterShouldClearTypeMismatchingData) {
  558. const std::string pref_name = "testing.pref";
  559. user_prefs_->SetString(pref_name, "string_value");
  560. ASSERT_TRUE(user_prefs_->GetValue(pref_name, nullptr));
  561. // Make sure no changes will be communicated to any synced pref listeners
  562. // (those listeners are typically only used for metrics but we still don't
  563. // want to inform them).
  564. ShouldNotBeNotifedObserver observer;
  565. prefs_.AddSyncedPrefObserver(pref_name, &observer);
  566. pref_registry_->RegisterListPref(
  567. pref_name, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  568. EXPECT_TRUE(GetPreferenceValue(pref_name).GetListDeprecated().empty());
  569. EXPECT_FALSE(user_prefs_->GetValue(pref_name, nullptr));
  570. prefs_.RemoveSyncedPrefObserver(pref_name, &observer);
  571. }
  572. TEST_F(PrefServiceSyncableMergeTest, ShouldIgnoreUpdatesToNotSyncablePrefs) {
  573. const std::string pref_name = "testing.not_syncable_pref";
  574. pref_registry_->RegisterStringPref(pref_name, "default_value",
  575. PrefRegistry::NO_REGISTRATION_FLAGS);
  576. syncer::SyncDataList in;
  577. AddToRemoteDataList(pref_name, base::Value("remote_value"), &in);
  578. syncer::SyncChangeList out;
  579. InitWithSyncDataTakeOutput(in, &out);
  580. EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
  581. syncer::SyncChangeList remote_changes;
  582. remote_changes.push_back(MakeRemoteChange(
  583. pref_name, base::Value("remote_value2"), SyncChange::ACTION_UPDATE));
  584. pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
  585. // The pref isn't synced.
  586. EXPECT_THAT(pref_sync_service_->GetAllSyncDataForTesting(syncer::PREFERENCES),
  587. IsEmpty());
  588. EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
  589. }
  590. TEST_F(PrefServiceSyncableTest, FailModelAssociation) {
  591. syncer::SyncChangeList output;
  592. TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output);
  593. stub->FailNextProcessSyncChanges();
  594. absl::optional<syncer::ModelError> error =
  595. pref_sync_service_->MergeDataAndStartSyncing(
  596. syncer::PREFERENCES, syncer::SyncDataList(), base::WrapUnique(stub),
  597. std::make_unique<syncer::SyncErrorFactoryMock>());
  598. EXPECT_TRUE(error.has_value());
  599. }
  600. TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithDefaultValue) {
  601. const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
  602. EXPECT_TRUE(pref->IsDefaultValue());
  603. syncer::SyncChangeList out;
  604. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  605. out.clear();
  606. base::Value expected(kExampleUrl0);
  607. GetPrefs()->Set(kStringPrefName, expected);
  608. std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
  609. ASSERT_TRUE(actual.get());
  610. EXPECT_EQ(expected, *actual);
  611. }
  612. TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithValue) {
  613. GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
  614. syncer::SyncChangeList out;
  615. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  616. out.clear();
  617. base::Value expected(kExampleUrl1);
  618. GetPrefs()->Set(kStringPrefName, expected);
  619. std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
  620. ASSERT_TRUE(actual.get());
  621. EXPECT_EQ(expected, *actual);
  622. }
  623. TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdate) {
  624. GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
  625. InitWithNoSyncData();
  626. base::Value expected(kExampleUrl1);
  627. syncer::SyncChangeList list;
  628. list.push_back(
  629. MakeRemoteChange(kStringPrefName, expected, SyncChange::ACTION_UPDATE));
  630. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  631. const base::Value& actual = GetPreferenceValue(kStringPrefName);
  632. EXPECT_EQ(expected, actual);
  633. }
  634. // Verifies that the implementation gracefully handles a remote update with the
  635. // wrong type. The local version should not get modified in these cases.
  636. TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdateTypeMismatch) {
  637. GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
  638. InitWithNoSyncData();
  639. base::Value remote_int_value(123);
  640. syncer::SyncChangeList remote_changes;
  641. remote_changes.push_back(MakeRemoteChange(kStringPrefName, remote_int_value,
  642. SyncChange::ACTION_UPDATE));
  643. pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
  644. EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
  645. }
  646. TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionAdd) {
  647. InitWithNoSyncData();
  648. base::Value expected(kExampleUrl0);
  649. syncer::SyncChangeList list;
  650. list.push_back(
  651. MakeRemoteChange(kStringPrefName, expected, SyncChange::ACTION_ADD));
  652. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  653. const base::Value& actual = GetPreferenceValue(kStringPrefName);
  654. EXPECT_EQ(expected, actual);
  655. EXPECT_TRUE(pref_sync_service_->IsPrefSyncedForTesting(kStringPrefName));
  656. }
  657. TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeUnknownPreference) {
  658. InitWithNoSyncData();
  659. syncer::SyncChangeList list;
  660. base::Value expected(kExampleUrl0);
  661. list.push_back(MakeRemoteChange("unknown preference", expected,
  662. SyncChange::ACTION_UPDATE));
  663. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  664. // Nothing interesting happens on the client when it gets an update
  665. // of an unknown preference. We just should not crash.
  666. }
  667. TEST_F(PrefServiceSyncableTest, ManagedPreferences) {
  668. // Make the homepage preference managed.
  669. base::Value managed_value("http://example.com");
  670. prefs_.SetManagedPref(kStringPrefName, managed_value.Clone());
  671. syncer::SyncChangeList out;
  672. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  673. out.clear();
  674. // Changing the homepage preference should not sync anything.
  675. base::Value user_value("http://chromium..com");
  676. prefs_.SetUserPref(kStringPrefName, user_value.Clone());
  677. EXPECT_TRUE(out.empty());
  678. // An incoming sync transaction should change the user value, not the managed
  679. // value.
  680. base::Value sync_value("http://crbug.com");
  681. syncer::SyncChangeList list;
  682. list.push_back(
  683. MakeRemoteChange(kStringPrefName, sync_value, SyncChange::ACTION_UPDATE));
  684. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  685. EXPECT_EQ(managed_value, *prefs_.GetManagedPref(kStringPrefName));
  686. EXPECT_EQ(sync_value, *prefs_.GetUserPref(kStringPrefName));
  687. }
  688. TEST_F(PrefServiceSyncableTest, DynamicManagedPreferences) {
  689. syncer::SyncChangeList out;
  690. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  691. out.clear();
  692. base::Value initial_value("http://example.com/initial");
  693. GetPrefs()->Set(kStringPrefName, initial_value);
  694. std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
  695. ASSERT_TRUE(actual.get());
  696. EXPECT_EQ(initial_value, *actual);
  697. // Switch kHomePage to managed and set a different value.
  698. base::Value managed_value("http://example.com/managed");
  699. GetTestingPrefService()->SetManagedPref(kStringPrefName,
  700. managed_value.Clone());
  701. // The pref value should be the one dictated by policy.
  702. EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
  703. // Switch kHomePage back to unmanaged.
  704. GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
  705. // The original value should be picked up.
  706. EXPECT_EQ(initial_value, GetPreferenceValue(kStringPrefName));
  707. }
  708. TEST_F(PrefServiceSyncableTest, DynamicManagedPreferencesWithSyncChange) {
  709. syncer::SyncChangeList out;
  710. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  711. out.clear();
  712. base::Value initial_value("http://example.com/initial");
  713. GetPrefs()->Set(kStringPrefName, initial_value);
  714. std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
  715. EXPECT_EQ(initial_value, *actual);
  716. // Switch kHomePage to managed and set a different value.
  717. base::Value managed_value("http://example.com/managed");
  718. GetTestingPrefService()->SetManagedPref(kStringPrefName,
  719. managed_value.Clone());
  720. // Change the sync value.
  721. base::Value sync_value("http://example.com/sync");
  722. syncer::SyncChangeList list;
  723. list.push_back(
  724. MakeRemoteChange(kStringPrefName, sync_value, SyncChange::ACTION_UPDATE));
  725. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  726. // The pref value should still be the one dictated by policy.
  727. EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
  728. // Switch kHomePage back to unmanaged.
  729. GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
  730. // Sync value should be picked up.
  731. EXPECT_EQ(sync_value, GetPreferenceValue(kStringPrefName));
  732. }
  733. TEST_F(PrefServiceSyncableTest, DynamicManagedDefaultPreferences) {
  734. const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
  735. EXPECT_TRUE(pref->IsDefaultValue());
  736. syncer::SyncChangeList out;
  737. InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
  738. EXPECT_TRUE(IsRegistered(kStringPrefName));
  739. EXPECT_TRUE(pref->IsDefaultValue());
  740. EXPECT_FALSE(FindValue(kStringPrefName, out).get());
  741. out.clear();
  742. // Switch kHomePage to managed and set a different value.
  743. base::Value managed_value("http://example.com/managed");
  744. GetTestingPrefService()->SetManagedPref(kStringPrefName,
  745. managed_value.Clone());
  746. // The pref value should be the one dictated by policy.
  747. EXPECT_EQ(managed_value, GetPreferenceValue(kStringPrefName));
  748. EXPECT_FALSE(pref->IsDefaultValue());
  749. // There should be no synced value.
  750. EXPECT_FALSE(FindValue(kStringPrefName, out).get());
  751. // Switch kHomePage back to unmanaged.
  752. GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
  753. // The original value should be picked up.
  754. EXPECT_TRUE(pref->IsDefaultValue());
  755. // There should still be no synced value.
  756. EXPECT_FALSE(FindValue(kStringPrefName, out).get());
  757. }
  758. TEST_F(PrefServiceSyncableTest, DeletePreference) {
  759. prefs_.SetString(kStringPrefName, kExampleUrl0);
  760. const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
  761. EXPECT_FALSE(pref->IsDefaultValue());
  762. InitWithNoSyncData();
  763. auto null_value = std::make_unique<base::Value>();
  764. syncer::SyncChangeList list;
  765. list.push_back(MakeRemoteChange(kStringPrefName, *null_value,
  766. SyncChange::ACTION_DELETE));
  767. pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
  768. EXPECT_TRUE(pref->IsDefaultValue());
  769. }
  770. #if BUILDFLAG(IS_CHROMEOS_ASH)
  771. // The Chrome OS tests exercise pref model association that happens in the
  772. // constructor of PrefServiceSyncable. The tests must register prefs first,
  773. // then create the PrefServiceSyncable object. The tests live in this file
  774. // because they share utility code with the cross-platform tests.
  775. class PrefServiceSyncableChromeOsTest : public testing::Test {
  776. public:
  777. PrefServiceSyncableChromeOsTest()
  778. : pref_registry_(base::MakeRefCounted<PrefRegistrySyncable>()),
  779. pref_notifier_(new PrefNotifierImpl),
  780. user_prefs_(base::MakeRefCounted<TestingPrefStore>()),
  781. standalone_browser_prefs_(base::MakeRefCounted<TestingPrefStore>()) {}
  782. void CreatePrefService() {
  783. // Register prefs of various types.
  784. pref_registry_->RegisterStringPref("unsynced_pref", std::string());
  785. pref_registry_->RegisterStringPref("browser_pref", std::string(),
  786. PrefRegistrySyncable::SYNCABLE_PREF);
  787. pref_registry_->RegisterStringPref(
  788. "browser_priority_pref", std::string(),
  789. PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
  790. pref_registry_->RegisterStringPref("os_pref", std::string(),
  791. PrefRegistrySyncable::SYNCABLE_OS_PREF);
  792. pref_registry_->RegisterStringPref(
  793. "os_priority_pref", std::string(),
  794. PrefRegistrySyncable::SYNCABLE_OS_PRIORITY_PREF);
  795. client_.SetIsDictPref(false);
  796. // Create the PrefServiceSyncable after prefs are registered, which is the
  797. // order used in production.
  798. prefs_ = std::make_unique<PrefServiceSyncable>(
  799. std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
  800. std::make_unique<PrefValueStore>(
  801. new TestingPrefStore, new TestingPrefStore, new TestingPrefStore,
  802. new TestingPrefStore, new TestingPrefStore, user_prefs_.get(),
  803. standalone_browser_prefs_.get(), pref_registry_->defaults().get(),
  804. pref_notifier_),
  805. user_prefs_, standalone_browser_prefs_, pref_registry_, &client_,
  806. /*read_error_callback=*/base::DoNothing(),
  807. /*async=*/false);
  808. }
  809. void InitSyncForType(ModelType type,
  810. syncer::SyncChangeList* output = nullptr) {
  811. syncer::SyncDataList empty_data;
  812. absl::optional<syncer::ModelError> error =
  813. prefs_->GetSyncableService(type)->MergeDataAndStartSyncing(
  814. type, empty_data, std::make_unique<TestSyncProcessorStub>(output),
  815. std::make_unique<syncer::SyncErrorFactoryMock>());
  816. EXPECT_FALSE(error.has_value());
  817. }
  818. void InitSyncForAllTypes(syncer::SyncChangeList* output = nullptr) {
  819. for (ModelType type : kAllPreferenceModelTypes) {
  820. InitSyncForType(type, output);
  821. }
  822. }
  823. ModelTypeSet GetRegisteredModelTypes(const std::string& pref_name) {
  824. ModelTypeSet registered_types;
  825. for (ModelType type : kAllPreferenceModelTypes) {
  826. if (static_cast<PrefModelAssociator*>(prefs_->GetSyncableService(type))
  827. ->IsPrefRegistered(pref_name)) {
  828. registered_types.Put(type);
  829. }
  830. }
  831. return registered_types;
  832. }
  833. SyncData MakeRemoteSyncData(const std::string& name,
  834. const base::Value& value,
  835. syncer::ModelType model_type) {
  836. std::string serialized;
  837. JSONStringValueSerializer json(&serialized);
  838. EXPECT_TRUE(json.Serialize(value));
  839. sync_pb::EntitySpecifics entity;
  840. sync_pb::PreferenceSpecifics* pref =
  841. PrefModelAssociator::GetMutableSpecifics(model_type, &entity);
  842. pref->set_name(name);
  843. pref->set_value(serialized);
  844. return SyncData::CreateRemoteData(
  845. entity, syncer::ClientTagHash::FromUnhashed(model_type, name));
  846. }
  847. protected:
  848. base::test::ScopedFeatureList feature_list_;
  849. scoped_refptr<PrefRegistrySyncable> pref_registry_;
  850. PrefNotifierImpl* pref_notifier_; // Owned by |prefs_|.
  851. scoped_refptr<TestingPrefStore> user_prefs_;
  852. scoped_refptr<TestingPrefStore> standalone_browser_prefs_;
  853. TestPrefModelAssociatorClient client_;
  854. std::unique_ptr<PrefServiceSyncable> prefs_;
  855. };
  856. TEST_F(PrefServiceSyncableChromeOsTest,
  857. IsPrefRegistered_CategorizationDisabled) {
  858. feature_list_.InitAndDisableFeature(
  859. chromeos::features::kSyncSettingsCategorization);
  860. CreatePrefService();
  861. EXPECT_TRUE(GetRegisteredModelTypes("unsynced_pref").Empty());
  862. EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
  863. GetRegisteredModelTypes("browser_pref"));
  864. EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
  865. GetRegisteredModelTypes("browser_priority_pref"));
  866. EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
  867. GetRegisteredModelTypes("os_pref"));
  868. EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
  869. GetRegisteredModelTypes("os_priority_pref"));
  870. }
  871. TEST_F(PrefServiceSyncableChromeOsTest,
  872. IsPrefRegistered_CategorizationEnabled) {
  873. feature_list_.InitAndEnableFeature(
  874. chromeos::features::kSyncSettingsCategorization);
  875. CreatePrefService();
  876. EXPECT_TRUE(GetRegisteredModelTypes("unsynced_pref").Empty());
  877. EXPECT_EQ(ModelTypeSet(syncer::PREFERENCES),
  878. GetRegisteredModelTypes("browser_pref"));
  879. EXPECT_EQ(ModelTypeSet(syncer::PRIORITY_PREFERENCES),
  880. GetRegisteredModelTypes("browser_priority_pref"));
  881. EXPECT_EQ(ModelTypeSet(syncer::OS_PREFERENCES),
  882. GetRegisteredModelTypes("os_pref"));
  883. EXPECT_EQ(ModelTypeSet(syncer::OS_PRIORITY_PREFERENCES),
  884. GetRegisteredModelTypes("os_priority_pref"));
  885. // The associator for PREFERENCES knows about OS prefs so that local updates
  886. // are synced back to old clients.
  887. auto* pref_associator = static_cast<PrefModelAssociator*>(
  888. prefs_->GetSyncableService(syncer::PREFERENCES));
  889. EXPECT_TRUE(pref_associator->IsLegacyModelTypePref("os_pref"));
  890. // The associator for PRIORITY_PREFERENCES knows about OS priority prefs so
  891. // that local updates are synced back to old clients.
  892. auto* priority_associator = static_cast<PrefModelAssociator*>(
  893. prefs_->GetSyncableService(syncer::PRIORITY_PREFERENCES));
  894. EXPECT_TRUE(priority_associator->IsLegacyModelTypePref("os_priority_pref"));
  895. }
  896. TEST_F(PrefServiceSyncableChromeOsTest, IsSyncing) {
  897. feature_list_.InitAndEnableFeature(
  898. chromeos::features::kSyncSettingsCategorization);
  899. CreatePrefService();
  900. InitSyncForType(syncer::PREFERENCES);
  901. EXPECT_TRUE(prefs_->IsSyncing());
  902. EXPECT_FALSE(prefs_->IsPrioritySyncing());
  903. EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
  904. EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
  905. }
  906. TEST_F(PrefServiceSyncableChromeOsTest, IsPrioritySyncing) {
  907. feature_list_.InitAndEnableFeature(
  908. chromeos::features::kSyncSettingsCategorization);
  909. CreatePrefService();
  910. InitSyncForType(syncer::PRIORITY_PREFERENCES);
  911. EXPECT_FALSE(prefs_->IsSyncing());
  912. EXPECT_TRUE(prefs_->IsPrioritySyncing());
  913. EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
  914. EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
  915. }
  916. TEST_F(PrefServiceSyncableChromeOsTest, AreOsPrefsSyncing) {
  917. feature_list_.InitAndEnableFeature(
  918. chromeos::features::kSyncSettingsCategorization);
  919. CreatePrefService();
  920. InitSyncForType(syncer::OS_PREFERENCES);
  921. EXPECT_FALSE(prefs_->IsSyncing());
  922. EXPECT_FALSE(prefs_->IsPrioritySyncing());
  923. EXPECT_TRUE(prefs_->AreOsPrefsSyncing());
  924. EXPECT_FALSE(prefs_->AreOsPriorityPrefsSyncing());
  925. }
  926. TEST_F(PrefServiceSyncableChromeOsTest, AreOsPriorityPrefsSyncing) {
  927. feature_list_.InitAndEnableFeature(
  928. chromeos::features::kSyncSettingsCategorization);
  929. CreatePrefService();
  930. InitSyncForType(syncer::OS_PRIORITY_PREFERENCES);
  931. EXPECT_FALSE(prefs_->IsSyncing());
  932. EXPECT_FALSE(prefs_->IsPrioritySyncing());
  933. EXPECT_FALSE(prefs_->AreOsPrefsSyncing());
  934. EXPECT_TRUE(prefs_->AreOsPriorityPrefsSyncing());
  935. }
  936. TEST_F(PrefServiceSyncableChromeOsTest, IsPrefSynced_OsPref) {
  937. feature_list_.InitAndEnableFeature(
  938. chromeos::features::kSyncSettingsCategorization);
  939. CreatePrefService();
  940. InitSyncForAllTypes();
  941. auto* associator = static_cast<PrefModelAssociator*>(
  942. prefs_->GetSyncableService(syncer::OS_PREFERENCES));
  943. EXPECT_FALSE(associator->IsPrefSyncedForTesting("os_pref"));
  944. syncer::SyncChangeList list;
  945. list.push_back(MakeRemoteChange("os_pref", base::Value("value"),
  946. SyncChange::ACTION_ADD,
  947. syncer::OS_PREFERENCES));
  948. associator->ProcessSyncChanges(FROM_HERE, list);
  949. EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
  950. }
  951. TEST_F(PrefServiceSyncableChromeOsTest, IsPrefSynced_OsPriorityPref) {
  952. feature_list_.InitAndEnableFeature(
  953. chromeos::features::kSyncSettingsCategorization);
  954. CreatePrefService();
  955. InitSyncForAllTypes();
  956. auto* associator = static_cast<PrefModelAssociator*>(
  957. prefs_->GetSyncableService(syncer::OS_PRIORITY_PREFERENCES));
  958. EXPECT_FALSE(associator->IsPrefSyncedForTesting("os_priority_pref"));
  959. syncer::SyncChangeList list;
  960. list.push_back(MakeRemoteChange("os_priority_pref", base::Value("value"),
  961. SyncChange::ACTION_ADD,
  962. syncer::OS_PRIORITY_PREFERENCES));
  963. associator->ProcessSyncChanges(FROM_HERE, list);
  964. EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_priority_pref"));
  965. }
  966. TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_OsPref) {
  967. feature_list_.InitAndEnableFeature(
  968. chromeos::features::kSyncSettingsCategorization);
  969. CreatePrefService();
  970. InitSyncForAllTypes();
  971. TestSyncedPrefObserver observer;
  972. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  973. prefs_->SetString("os_pref", "value");
  974. EXPECT_EQ("os_pref", observer.last_pref_);
  975. EXPECT_EQ(1, observer.changed_count_);
  976. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  977. }
  978. TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_OsPriorityPref) {
  979. feature_list_.InitAndEnableFeature(
  980. chromeos::features::kSyncSettingsCategorization);
  981. CreatePrefService();
  982. InitSyncForAllTypes();
  983. TestSyncedPrefObserver observer;
  984. prefs_->AddSyncedPrefObserver("os_priority_pref", &observer);
  985. prefs_->SetString("os_priority_pref", "value");
  986. EXPECT_EQ("os_priority_pref", observer.last_pref_);
  987. EXPECT_EQ(1, observer.changed_count_);
  988. prefs_->RemoveSyncedPrefObserver("os_priority_pref", &observer);
  989. }
  990. TEST_F(PrefServiceSyncableChromeOsTest,
  991. OsPrefChangeSyncedAsBrowserPrefChange_CategorizationDisabled) {
  992. feature_list_.InitAndDisableFeature(
  993. chromeos::features::kSyncSettingsCategorization);
  994. CreatePrefService();
  995. // Set a non-default value.
  996. prefs_->SetString("os_pref", "new_value");
  997. // Start syncing.
  998. syncer::SyncChangeList output;
  999. InitSyncForAllTypes(&output);
  1000. ASSERT_EQ(1u, output.size());
  1001. // The OS pref is treated like a browser pref.
  1002. EXPECT_EQ(syncer::PREFERENCES, output[0].sync_data().GetDataType());
  1003. }
  1004. TEST_F(PrefServiceSyncableChromeOsTest,
  1005. OsPrefChangeSyncedAsOsPrefChange_CategorizationEnabled) {
  1006. feature_list_.InitAndEnableFeature(
  1007. chromeos::features::kSyncSettingsCategorization);
  1008. CreatePrefService();
  1009. // Set a non-default value.
  1010. prefs_->SetString("os_pref", "new_value");
  1011. // Start syncing.
  1012. syncer::SyncChangeList output;
  1013. InitSyncForAllTypes(&output);
  1014. ASSERT_EQ(1u, output.size());
  1015. // The OS pref is treated like an OS pref.
  1016. EXPECT_EQ(syncer::OS_PREFERENCES, output[0].sync_data().GetDataType());
  1017. // Future changes will be synced back to browser preferences as well.
  1018. auto* associator = static_cast<PrefModelAssociator*>(
  1019. prefs_->GetSyncableService(syncer::PREFERENCES));
  1020. EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
  1021. }
  1022. TEST_F(PrefServiceSyncableChromeOsTest,
  1023. OsPrefChangeMakesSyncChangeForOldClients_CategorizationEnabled_Update) {
  1024. feature_list_.InitAndEnableFeature(
  1025. chromeos::features::kSyncSettingsCategorization);
  1026. CreatePrefService();
  1027. syncer::SyncChangeList changes;
  1028. InitSyncForAllTypes(&changes);
  1029. EXPECT_THAT(changes, IsEmpty());
  1030. // Make a local change.
  1031. prefs_->SetString("os_pref", "new_value");
  1032. // Sync changes are made for the legacy ModelType::PREFERENCES (so old clients
  1033. // will get updates) and for the current ModelType::OS_PREFERENCES (so new
  1034. // clients will get updates).
  1035. EXPECT_THAT(changes,
  1036. UnorderedElementsAre(MatchesModelType(syncer::PREFERENCES),
  1037. MatchesModelType(syncer::OS_PREFERENCES)));
  1038. // Future changes will be synced back to browser preferences as well.
  1039. auto* associator = static_cast<PrefModelAssociator*>(
  1040. prefs_->GetSyncableService(syncer::PREFERENCES));
  1041. EXPECT_TRUE(associator->IsPrefSyncedForTesting("os_pref"));
  1042. }
  1043. TEST_F(PrefServiceSyncableChromeOsTest,
  1044. UpdatesFromOldClientsAreIgnored_Startup) {
  1045. feature_list_.InitAndEnableFeature(
  1046. chromeos::features::kSyncSettingsCategorization);
  1047. CreatePrefService();
  1048. TestSyncedPrefObserver observer;
  1049. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  1050. // Simulate an old client that has "os_pref" registered as SYNCABLE_PREF
  1051. // instead of SYNCABLE_OS_PREF.
  1052. syncer::SyncDataList list;
  1053. list.push_back(CreateRemoteSyncData("os_pref", base::Value("new_value")));
  1054. // Simulate the first sync at startup of the legacy browser prefs ModelType.
  1055. auto* browser_associator = static_cast<PrefModelAssociator*>(
  1056. prefs_->GetSyncableService(syncer::PREFERENCES));
  1057. syncer::SyncChangeList outgoing_changes;
  1058. browser_associator->MergeDataAndStartSyncing(
  1059. syncer::PREFERENCES, list,
  1060. std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
  1061. std::make_unique<syncer::SyncErrorFactoryMock>());
  1062. // No outgoing changes were triggered.
  1063. EXPECT_TRUE(outgoing_changes.empty());
  1064. // The value from the old client was not applied.
  1065. EXPECT_NE("new_value", prefs_->GetString("os_pref"));
  1066. // The pref is not considered to be syncing, because it still has its default
  1067. // value.
  1068. EXPECT_FALSE(browser_associator->IsPrefSyncedForTesting("os_pref"));
  1069. // Observers were not notified of changes.
  1070. EXPECT_EQ(0, observer.changed_count_);
  1071. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  1072. }
  1073. TEST_F(PrefServiceSyncableChromeOsTest,
  1074. UpdatesFromOldClientsAreIgnored_Update) {
  1075. feature_list_.InitAndEnableFeature(
  1076. chromeos::features::kSyncSettingsCategorization);
  1077. CreatePrefService();
  1078. InitSyncForAllTypes();
  1079. TestSyncedPrefObserver observer;
  1080. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  1081. syncer::SyncChangeList list;
  1082. // Simulate an old client that has "os_pref" registered as SYNCABLE_PREF
  1083. // instead of SYNCABLE_OS_PREF.
  1084. list.push_back(MakeRemoteChange("os_pref", base::Value("new_value"),
  1085. SyncChange::ACTION_ADD, syncer::PREFERENCES));
  1086. // Simulate a sync update after startup.
  1087. prefs_->GetSyncableService(syncer::PREFERENCES)
  1088. ->ProcessSyncChanges(FROM_HERE, list);
  1089. // Update was not applied.
  1090. EXPECT_NE("new_value", prefs_->GetString("os_pref"));
  1091. // Observers were not notified of changes.
  1092. EXPECT_EQ(0, observer.changed_count_);
  1093. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  1094. }
  1095. TEST_F(PrefServiceSyncableChromeOsTest,
  1096. SyncedPrefObserver_OsPrefIsChangedFromSync) {
  1097. feature_list_.InitAndEnableFeature(
  1098. chromeos::features::kSyncSettingsCategorization);
  1099. CreatePrefService();
  1100. prefs_->SetString("os_pref", "default_value");
  1101. TestSyncedPrefObserver observer;
  1102. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  1103. TestPrefServiceSyncableObserver pref_service_sync_observer;
  1104. pref_service_sync_observer.SetSyncedPrefObserver(&observer);
  1105. prefs_->AddObserver(&pref_service_sync_observer);
  1106. // Simulate that "os_pref" is registered as SYNCABLE_PREF
  1107. syncer::SyncDataList list;
  1108. list.push_back(MakeRemoteSyncData("os_pref", base::Value("new_value"),
  1109. syncer::OS_PREFERENCES));
  1110. // Simulate the first sync at startup.
  1111. syncer::SyncChangeList outgoing_changes;
  1112. prefs_->GetSyncableService(syncer::OS_PREFERENCES)
  1113. ->MergeDataAndStartSyncing(
  1114. syncer::OS_PREFERENCES, list,
  1115. std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
  1116. std::make_unique<syncer::SyncErrorFactoryMock>());
  1117. EXPECT_EQ("os_pref", observer.synced_pref_);
  1118. EXPECT_EQ(1, observer.sync_started_count_);
  1119. EXPECT_TRUE(pref_service_sync_observer.is_syncing_changed());
  1120. prefs_->RemoveObserver(&pref_service_sync_observer);
  1121. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  1122. }
  1123. TEST_F(PrefServiceSyncableChromeOsTest,
  1124. SyncedPrefObserver_OsPrefIsNotChangedFromSync) {
  1125. feature_list_.InitAndEnableFeature(
  1126. chromeos::features::kSyncSettingsCategorization);
  1127. CreatePrefService();
  1128. prefs_->SetString("os_pref", "default_value");
  1129. TestSyncedPrefObserver observer;
  1130. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  1131. TestPrefServiceSyncableObserver pref_service_sync_observer;
  1132. pref_service_sync_observer.SetSyncedPrefObserver(&observer);
  1133. prefs_->AddObserver(&pref_service_sync_observer);
  1134. // Simulate that "os_pref" is registered as SYNCABLE_PREF
  1135. syncer::SyncDataList list;
  1136. list.push_back(MakeRemoteSyncData("os_pref", base::Value("new_value"),
  1137. syncer::OS_PREFERENCES));
  1138. // Simulate the first sync at startup.
  1139. syncer::SyncChangeList outgoing_changes;
  1140. prefs_->GetSyncableService(syncer::OS_PREFERENCES)
  1141. ->MergeDataAndStartSyncing(
  1142. syncer::OS_PREFERENCES, list,
  1143. std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
  1144. std::make_unique<syncer::SyncErrorFactoryMock>());
  1145. EXPECT_EQ("os_pref", observer.synced_pref_);
  1146. EXPECT_EQ(1, observer.sync_started_count_);
  1147. EXPECT_TRUE(pref_service_sync_observer.is_syncing_changed());
  1148. prefs_->RemoveObserver(&pref_service_sync_observer);
  1149. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  1150. }
  1151. TEST_F(PrefServiceSyncableChromeOsTest, SyncedPrefObserver_EmptyCloud) {
  1152. feature_list_.InitAndEnableFeature(
  1153. chromeos::features::kSyncSettingsCategorization);
  1154. CreatePrefService();
  1155. prefs_->SetString("os_pref", "new_value");
  1156. TestSyncedPrefObserver observer;
  1157. prefs_->AddSyncedPrefObserver("os_pref", &observer);
  1158. // Simulate the first sync at startup.
  1159. syncer::SyncChangeList outgoing_changes;
  1160. prefs_->GetSyncableService(syncer::OS_PREFERENCES)
  1161. ->MergeDataAndStartSyncing(
  1162. syncer::OS_PREFERENCES, syncer::SyncDataList(),
  1163. std::make_unique<TestSyncProcessorStub>(&outgoing_changes),
  1164. std::make_unique<syncer::SyncErrorFactoryMock>());
  1165. EXPECT_EQ("", observer.synced_pref_);
  1166. EXPECT_EQ(0, observer.sync_started_count_);
  1167. prefs_->RemoveSyncedPrefObserver("os_pref", &observer);
  1168. }
  1169. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  1170. } // namespace
  1171. } // namespace sync_preferences