1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
163003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_PREFS_H_
1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_PREFS_H_
193003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
20d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo#include <map>
21d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <string>
22d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo#include <vector>
23d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko
2475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/files/file_path.h>
25d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo
263003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov#include "gtest/gtest_prod.h"  // for FRIEND_TEST
2739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/prefs_interface.h"
283003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
293003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkovnamespace chromeos_update_engine {
303003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
31e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// Implements a preference store by storing the value associated with a key
32e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// in a given storage passed during construction.
33e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymoclass PrefsBase : public PrefsInterface {
343003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov public:
35e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // Storage interface used to set and retrieve keys.
36e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  class StorageInterface {
37e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   public:
38e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    StorageInterface() = default;
39e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    virtual ~StorageInterface() = default;
401cbd78ffe68039a5781c3434816e03e64033dc0bDarin Petkov
41e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Get the key named |key| and store its value in the referenced |value|.
42e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Returns whether the operation succeeded.
43e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    virtual bool GetKey(const std::string& key, std::string* value) const = 0;
44e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
45e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Set the value of the key named |key| to |value| regardless of the
46e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // previous value. Returns whether the operation succeeded.
47e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    virtual bool SetKey(const std::string& key, const std::string& value) = 0;
48e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
49e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Returns whether the key named |key| exists.
50e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    virtual bool KeyExists(const std::string& key) const = 0;
51e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
52e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Deletes the value associated with the key name |key|. Returns whether the
53e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // key was deleted.
54e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    virtual bool DeleteKey(const std::string& key) = 0;
55e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
56e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   private:
57e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    DISALLOW_COPY_AND_ASSIGN(StorageInterface);
58e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  };
59e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
60e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  explicit PrefsBase(StorageInterface* storage) : storage_(storage) {}
613003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
623003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov  // PrefsInterface methods.
63d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  bool GetString(const std::string& key, std::string* value) const override;
64610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool SetString(const std::string& key, const std::string& value) override;
65d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  bool GetInt64(const std::string& key, int64_t* value) const override;
66610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool SetInt64(const std::string& key, const int64_t value) override;
67d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  bool GetBoolean(const std::string& key, bool* value) const override;
68610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool SetBoolean(const std::string& key, const bool value) override;
69610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo
70d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  bool Exists(const std::string& key) const override;
71610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool Delete(const std::string& key) override;
72480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan
73d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  void AddObserver(const std::string& key,
74d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo                   ObserverInterface* observer) override;
75d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo  void RemoveObserver(const std::string& key,
76d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo                      ObserverInterface* observer) override;
77d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo
783003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov private:
79e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // The registered observers watching for changes.
80e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  std::map<std::string, std::vector<ObserverInterface*>> observers_;
81e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
82e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // The concrete implementation of the storage used for the keys.
83e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  StorageInterface* storage_;
84e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
85e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  DISALLOW_COPY_AND_ASSIGN(PrefsBase);
86e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo};
87e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
88e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// Implements a preference store by storing the value associated with
89e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// a key in a separate file named after the key under a preference
90e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// store directory.
91e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
92e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymoclass Prefs : public PrefsBase {
93e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo public:
94e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  Prefs() : PrefsBase(&file_storage_) {}
95e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
96e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // Initializes the store by associating this object with |prefs_dir|
97e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // as the preference store directory. Returns true on success, false
98e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // otherwise.
99e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  bool Init(const base::FilePath& prefs_dir);
100e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
101e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo private:
1023003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov  FRIEND_TEST(PrefsTest, GetFileNameForKey);
1033003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov  FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
1043003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov  FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
1053003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
106e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  class FileStorage : public PrefsBase::StorageInterface {
107e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   public:
108e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    FileStorage() = default;
1093003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
110e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool Init(const base::FilePath& prefs_dir);
1111cbd78ffe68039a5781c3434816e03e64033dc0bDarin Petkov
112e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // PrefsBase::StorageInterface overrides.
113e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool GetKey(const std::string& key, std::string* value) const override;
114e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool SetKey(const std::string& key, const std::string& value) override;
115e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool KeyExists(const std::string& key) const override;
116e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool DeleteKey(const std::string& key) override;
117e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
118e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   private:
119e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    FRIEND_TEST(PrefsTest, GetFileNameForKey);
120e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
121e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
122e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
123e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Sets |filename| to the full path to the file containing the data
124e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // associated with |key|. Returns true on success, false otherwise.
125e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool GetFileNameForKey(const std::string& key,
126e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo                           base::FilePath* filename) const;
127e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
128e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // Preference store directory.
129e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    base::FilePath prefs_dir_;
130e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  };
131e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
132e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // The concrete file storage implementation.
133e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  FileStorage file_storage_;
134d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo
1351cbd78ffe68039a5781c3434816e03e64033dc0bDarin Petkov  DISALLOW_COPY_AND_ASSIGN(Prefs);
1363003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov};
1373003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
138e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// Implements a preference store in memory. The stored values are lost when the
139e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo// object is destroyed.
140e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
141e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymoclass MemoryPrefs : public PrefsBase {
142e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo public:
143e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  MemoryPrefs() : PrefsBase(&mem_storage_) {}
144e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
145e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo private:
146e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  class MemoryStorage : public PrefsBase::StorageInterface {
147e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   public:
148e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    MemoryStorage() = default;
149e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
150e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // PrefsBase::StorageInterface overrides.
151e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool GetKey(const std::string& key, std::string* value) const override;
152e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool SetKey(const std::string& key, const std::string& value) override;
153e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool KeyExists(const std::string& key) const override;
154e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    bool DeleteKey(const std::string& key) override;
155e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
156e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo   private:
157e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    // The std::map holding the values in memory.
158e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo    std::map<std::string, std::string> values_;
159e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  };
160e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
161e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  // The concrete memory storage implementation.
162e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  MemoryStorage mem_storage_;
163e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo
164e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo  DISALLOW_COPY_AND_ASSIGN(MemoryPrefs);
165e6eef83c63a50f043b2c4a85175030b6d8b6b91dAlex Deymo};
1663003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov}  // namespace chromeos_update_engine
1673003059032a7ac8a49f1bdd9fda2d58becec8374Darin Petkov
16839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_PREFS_H_
169