// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_ #define COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_ #include <memory> #include <utility> #include "base/memory/ref_counted.h" #include "components/prefs/pref_registry.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_store.h" class PrefNotifierImpl; class PrefRegistrySimple; class TestingPrefStore; // A PrefService subclass for testing. It operates totally in memory and // provides additional API for manipulating preferences at the different levels // (managed, extension, user) conveniently. // // Use this via its specializations, e.g. TestingPrefServiceSimple. template <class SuperPrefService, class ConstructionPrefRegistry> class TestingPrefServiceBase : public SuperPrefService { public: TestingPrefServiceBase(const TestingPrefServiceBase&) = delete; TestingPrefServiceBase& operator=(const TestingPrefServiceBase&) = delete; virtual ~TestingPrefServiceBase(); // Reads the value of a preference from the managed layer. Returns NULL if the // preference is not defined at the managed layer. const base::Value* GetManagedPref(const std::string& path) const; // Sets a preference on the managed layer and fires observers if the // preference changed. void SetManagedPref(const std::string& path, std::unique_ptr<base::Value> value); void SetManagedPref(const std::string& path, base::Value value); void SetManagedPref(const std::string& path, base::Value::Dict dict); void SetManagedPref(const std::string& path, base::Value::List list); // Clears the preference on the managed layer and fire observers if the // preference has been defined previously. void RemoveManagedPref(const std::string& path); // Similar to the above, but for supervised user preferences. const base::Value* GetSupervisedUserPref(const std::string& path) const; void SetSupervisedUserPref(const std::string& path, std::unique_ptr<base::Value> value); void SetSupervisedUserPref(const std::string& path, base::Value value); void SetSupervisedUserPref(const std::string& path, base::Value::Dict dict); void SetSupervisedUserPref(const std::string& path, base::Value::List list); void RemoveSupervisedUserPref(const std::string& path); // Similar to the above, but for extension preferences. // Does not really know about extensions and their order of installation. // Useful in tests that only check that a preference is overridden by an // extension. const base::Value* GetExtensionPref(const std::string& path) const; void SetExtensionPref(const std::string& path, std::unique_ptr<base::Value> value); void SetExtensionPref(const std::string& path, base::Value value); void SetExtensionPref(const std::string& path, base::Value::Dict dict); void SetExtensionPref(const std::string& path, base::Value::List list); void RemoveExtensionPref(const std::string& path); // Similar to the above, but for user preferences. const base::Value* GetUserPref(const std::string& path) const; void SetUserPref(const std::string& path, std::unique_ptr<base::Value> value); void SetUserPref(const std::string& path, base::Value value); void SetUserPref(const std::string& path, base::Value::Dict dict); void SetUserPref(const std::string& path, base::Value::List list); void RemoveUserPref(const std::string& path); // Similar to the above, but for recommended policy preferences. const base::Value* GetRecommendedPref(const std::string& path) const; void SetRecommendedPref(const std::string& path, std::unique_ptr<base::Value> value); void SetRecommendedPref(const std::string& path, base::Value value); void SetRecommendedPref(const std::string& path, base::Value::Dict dict); void SetRecommendedPref(const std::string& path, base::Value::List list); void RemoveRecommendedPref(const std::string& path); // Do-nothing implementation for TestingPrefService. static void HandleReadError(PersistentPrefStore::PrefReadError error) {} // Set initialization status of pref stores. void SetInitializationCompleted(); scoped_refptr<TestingPrefStore> user_prefs_store() { return user_prefs_; } protected: TestingPrefServiceBase( scoped_refptr<TestingPrefStore> managed_prefs, scoped_refptr<TestingPrefStore> supervised_user_prefs, scoped_refptr<TestingPrefStore> extension_prefs, scoped_refptr<TestingPrefStore> standalone_browser_prefs, scoped_refptr<TestingPrefStore> user_prefs, scoped_refptr<TestingPrefStore> recommended_prefs, scoped_refptr<ConstructionPrefRegistry> pref_registry, // Takes ownership. PrefNotifierImpl* pref_notifier); private: // Reads the value of the preference indicated by |path| from |pref_store|. // Returns NULL if the preference was not found. const base::Value* GetPref(TestingPrefStore* pref_store, const std::string& path) const; // Sets the value for |path| in |pref_store|. void SetPref(TestingPrefStore* pref_store, const std::string& path, std::unique_ptr<base::Value> value); // Removes the preference identified by |path| from |pref_store|. void RemovePref(TestingPrefStore* pref_store, const std::string& path); // Pointers to the pref stores our value store uses. scoped_refptr<TestingPrefStore> managed_prefs_; scoped_refptr<TestingPrefStore> supervised_user_prefs_; scoped_refptr<TestingPrefStore> extension_prefs_; scoped_refptr<TestingPrefStore> standalone_browser_prefs_; scoped_refptr<TestingPrefStore> user_prefs_; scoped_refptr<TestingPrefStore> recommended_prefs_; }; // Test version of PrefService. class TestingPrefServiceSimple : public TestingPrefServiceBase<PrefService, PrefRegistry> { public: TestingPrefServiceSimple(); TestingPrefServiceSimple(const TestingPrefServiceSimple&) = delete; TestingPrefServiceSimple& operator=(const TestingPrefServiceSimple&) = delete; ~TestingPrefServiceSimple() override; // This is provided as a convenience for registering preferences on // an existing TestingPrefServiceSimple instance. On a production // PrefService you would do all registrations before constructing // it, passing it a PrefRegistry via its constructor (or via // e.g. PrefServiceFactory). PrefRegistrySimple* registry(); }; template <> TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase( scoped_refptr<TestingPrefStore> managed_prefs, scoped_refptr<TestingPrefStore> supervised_user_prefs, scoped_refptr<TestingPrefStore> extension_prefs, scoped_refptr<TestingPrefStore> standalone_browser_prefs, scoped_refptr<TestingPrefStore> user_prefs, scoped_refptr<TestingPrefStore> recommended_prefs, scoped_refptr<PrefRegistry> pref_registry, PrefNotifierImpl* pref_notifier); template<class SuperPrefService, class ConstructionPrefRegistry> TestingPrefServiceBase< SuperPrefService, ConstructionPrefRegistry>::~TestingPrefServiceBase() { } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase< SuperPrefService, ConstructionPrefRegistry>::GetManagedPref(const std::string& path) const { return GetPref(managed_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetManagedPref(const std::string& path, std::unique_ptr<base::Value> value) { SetPref(managed_prefs_.get(), path, std::move(value)); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetManagedPref(const std::string& path, base::Value value) { SetManagedPref(path, base::Value::ToUniquePtrValue(std::move(value))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetManagedPref(const std::string& path, base::Value::Dict dict) { SetManagedPref(path, std::make_unique<base::Value>(std::move(dict))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetManagedPref(const std::string& path, base::Value::List list) { SetManagedPref(path, std::make_unique<base::Value>(std::move(list))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemoveManagedPref(const std::string& path) { RemovePref(managed_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: GetSupervisedUserPref(const std::string& path) const { return GetPref(supervised_user_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetSupervisedUserPref(const std::string& path, std::unique_ptr<base::Value> value) { SetPref(supervised_user_prefs_.get(), path, std::move(value)); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetSupervisedUserPref(const std::string& path, base::Value value) { SetSupervisedUserPref(path, base::Value::ToUniquePtrValue(std::move(value))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetSupervisedUserPref(const std::string& path, base::Value::Dict dict) { SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(dict))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetSupervisedUserPref(const std::string& path, base::Value::List list) { SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(list))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemoveSupervisedUserPref(const std::string& path) { RemovePref(supervised_user_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase< SuperPrefService, ConstructionPrefRegistry>::GetExtensionPref(const std::string& path) const { return GetPref(extension_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetExtensionPref(const std::string& path, std::unique_ptr<base::Value> value) { SetPref(extension_prefs_.get(), path, std::move(value)); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetExtensionPref(const std::string& path, base::Value value) { SetExtensionPref(path, base::Value::ToUniquePtrValue(std::move(value))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetExtensionPref(const std::string& path, base::Value::Dict dict) { SetExtensionPref(path, std::make_unique<base::Value>(std::move(dict))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetExtensionPref(const std::string& path, base::Value::List list) { SetExtensionPref(path, std::make_unique<base::Value>(std::move(list))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemoveExtensionPref(const std::string& path) { RemovePref(extension_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetUserPref( const std::string& path) const { return GetPref(user_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetUserPref(const std::string& path, std::unique_ptr<base::Value> value) { SetPref(user_prefs_.get(), path, std::move(value)); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetUserPref(const std::string& path, base::Value value) { SetUserPref(path, base::Value::ToUniquePtrValue(std::move(value))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetUserPref(const std::string& path, base::Value::Dict dict) { SetUserPref(path, std::make_unique<base::Value>(std::move(dict))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetUserPref(const std::string& path, base::Value::List list) { SetUserPref(path, std::make_unique<base::Value>(std::move(list))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemoveUserPref(const std::string& path) { RemovePref(user_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: GetRecommendedPref(const std::string& path) const { return GetPref(recommended_prefs_, path); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetRecommendedPref(const std::string& path, std::unique_ptr<base::Value> value) { SetPref(recommended_prefs_.get(), path, std::move(value)); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetRecommendedPref(const std::string& path, base::Value value) { SetPref(recommended_prefs_.get(), path, base::Value::ToUniquePtrValue(std::move(value))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetRecommendedPref(const std::string& path, base::Value::Dict dict) { SetRecommendedPref(path, std::make_unique<base::Value>(std::move(dict))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetRecommendedPref(const std::string& path, base::Value::List list) { SetRecommendedPref(path, std::make_unique<base::Value>(std::move(list))); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemoveRecommendedPref(const std::string& path) { RemovePref(recommended_prefs_.get(), path); } template <class SuperPrefService, class ConstructionPrefRegistry> const base::Value* TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetPref( TestingPrefStore* pref_store, const std::string& path) const { const base::Value* res; return pref_store->GetValue(path, &res) ? res : NULL; } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetPref(TestingPrefStore* pref_store, const std::string& path, std::unique_ptr<base::Value> value) { pref_store->SetValue(path, base::Value::FromUniquePtrValue(std::move(value)), WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: RemovePref(TestingPrefStore* pref_store, const std::string& path) { pref_store->RemoveValue(path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); } template <class SuperPrefService, class ConstructionPrefRegistry> void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>:: SetInitializationCompleted() { managed_prefs_->SetInitializationCompleted(); supervised_user_prefs_->SetInitializationCompleted(); extension_prefs_->SetInitializationCompleted(); recommended_prefs_->SetInitializationCompleted(); // |user_prefs_| and |standalone_browser_prefs_| are initialized in // PrefService constructor so no need to set initialization status again. } #endif // COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_