Implement a memory-based Prefs class.
When the /data storage is not available, we need to store the required
prefs in memory to keep all the code working. This patch splits the
Prefs class functionality and implements a MemoryPrefs class which
stores all the values in memory.
Bug: 27178350
TEST=Added unittest for the MemoryPrefs.
Change-Id: I11f871ddb73e2f33db4101705efb293e1cbe0023
diff --git a/common/prefs.h b/common/prefs.h
index f11abc3..0116454 100644
--- a/common/prefs.h
+++ b/common/prefs.h
@@ -28,18 +28,36 @@
namespace chromeos_update_engine {
-// Implements a preference store by storing the value associated with
-// a key in a separate file named after the key under a preference
-// store directory.
-
-class Prefs : public PrefsInterface {
+// Implements a preference store by storing the value associated with a key
+// in a given storage passed during construction.
+class PrefsBase : public PrefsInterface {
public:
- Prefs() = default;
+ // Storage interface used to set and retrieve keys.
+ class StorageInterface {
+ public:
+ StorageInterface() = default;
+ virtual ~StorageInterface() = default;
- // Initializes the store by associating this object with |prefs_dir|
- // as the preference store directory. Returns true on success, false
- // otherwise.
- bool Init(const base::FilePath& prefs_dir);
+ // Get the key named |key| and store its value in the referenced |value|.
+ // Returns whether the operation succeeded.
+ virtual bool GetKey(const std::string& key, std::string* value) const = 0;
+
+ // Set the value of the key named |key| to |value| regardless of the
+ // previous value. Returns whether the operation succeeded.
+ virtual bool SetKey(const std::string& key, const std::string& value) = 0;
+
+ // Returns whether the key named |key| exists.
+ virtual bool KeyExists(const std::string& key) const = 0;
+
+ // Deletes the value associated with the key name |key|. Returns whether the
+ // key was deleted.
+ virtual bool DeleteKey(const std::string& key) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StorageInterface);
+ };
+
+ explicit PrefsBase(StorageInterface* storage) : storage_(storage) {}
// PrefsInterface methods.
bool GetString(const std::string& key, std::string* value) const override;
@@ -58,24 +76,93 @@
ObserverInterface* observer) override;
private:
+ // The registered observers watching for changes.
+ std::map<std::string, std::vector<ObserverInterface*>> observers_;
+
+ // The concrete implementation of the storage used for the keys.
+ StorageInterface* storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefsBase);
+};
+
+// Implements a preference store by storing the value associated with
+// a key in a separate file named after the key under a preference
+// store directory.
+
+class Prefs : public PrefsBase {
+ public:
+ Prefs() : PrefsBase(&file_storage_) {}
+
+ // Initializes the store by associating this object with |prefs_dir|
+ // as the preference store directory. Returns true on success, false
+ // otherwise.
+ bool Init(const base::FilePath& prefs_dir);
+
+ private:
FRIEND_TEST(PrefsTest, GetFileNameForKey);
FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
- // Sets |filename| to the full path to the file containing the data
- // associated with |key|. Returns true on success, false otherwise.
- bool GetFileNameForKey(const std::string& key,
- base::FilePath* filename) const;
+ class FileStorage : public PrefsBase::StorageInterface {
+ public:
+ FileStorage() = default;
- // Preference store directory.
- base::FilePath prefs_dir_;
+ bool Init(const base::FilePath& prefs_dir);
- // The registered observers watching for changes.
- std::map<std::string, std::vector<ObserverInterface*>> observers_;
+ // PrefsBase::StorageInterface overrides.
+ bool GetKey(const std::string& key, std::string* value) const override;
+ bool SetKey(const std::string& key, const std::string& value) override;
+ bool KeyExists(const std::string& key) const override;
+ bool DeleteKey(const std::string& key) override;
+
+ private:
+ FRIEND_TEST(PrefsTest, GetFileNameForKey);
+ FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
+ FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
+
+ // Sets |filename| to the full path to the file containing the data
+ // associated with |key|. Returns true on success, false otherwise.
+ bool GetFileNameForKey(const std::string& key,
+ base::FilePath* filename) const;
+
+ // Preference store directory.
+ base::FilePath prefs_dir_;
+ };
+
+ // The concrete file storage implementation.
+ FileStorage file_storage_;
DISALLOW_COPY_AND_ASSIGN(Prefs);
};
+// Implements a preference store in memory. The stored values are lost when the
+// object is destroyed.
+
+class MemoryPrefs : public PrefsBase {
+ public:
+ MemoryPrefs() : PrefsBase(&mem_storage_) {}
+
+ private:
+ class MemoryStorage : public PrefsBase::StorageInterface {
+ public:
+ MemoryStorage() = default;
+
+ // PrefsBase::StorageInterface overrides.
+ bool GetKey(const std::string& key, std::string* value) const override;
+ bool SetKey(const std::string& key, const std::string& value) override;
+ bool KeyExists(const std::string& key) const override;
+ bool DeleteKey(const std::string& key) override;
+
+ private:
+ // The std::map holding the values in memory.
+ std::map<std::string, std::string> values_;
+ };
+
+ // The concrete memory storage implementation.
+ MemoryStorage mem_storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(MemoryPrefs);
+};
} // namespace chromeos_update_engine
#endif // UPDATE_ENGINE_COMMON_PREFS_H_