1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef UPDATE_ENGINE_COMMON_PREFS_H_
18 #define UPDATE_ENGINE_COMMON_PREFS_H_
19 
20 #include <map>
21 #include <string>
22 #include <vector>
23 
24 #include <base/files/file_path.h>
25 
26 #include "gtest/gtest_prod.h"  // for FRIEND_TEST
27 #include "update_engine/common/prefs_interface.h"
28 
29 namespace chromeos_update_engine {
30 
31 // Implements a preference store by storing the value associated with a key
32 // in a given storage passed during construction.
33 class PrefsBase : public PrefsInterface {
34  public:
35   // Storage interface used to set and retrieve keys.
36   class StorageInterface {
37    public:
38     StorageInterface() = default;
39     virtual ~StorageInterface() = default;
40 
41     // Get the key named |key| and store its value in the referenced |value|.
42     // Returns whether the operation succeeded.
43     virtual bool GetKey(const std::string& key, std::string* value) const = 0;
44 
45     // Get the keys stored within the namespace. If there are no keys in the
46     // namespace, |keys| will be empty. Returns whether the operation succeeded.
47     virtual bool GetSubKeys(const std::string& ns,
48                             std::vector<std::string>* keys) const = 0;
49 
50     // Set the value of the key named |key| to |value| regardless of the
51     // previous value. Returns whether the operation succeeded.
52     virtual bool SetKey(const std::string& key, const std::string& value) = 0;
53 
54     // Returns whether the key named |key| exists.
55     virtual bool KeyExists(const std::string& key) const = 0;
56 
57     // Deletes the value associated with the key name |key|. Returns whether the
58     // key was deleted.
59     virtual bool DeleteKey(const std::string& key) = 0;
60 
61    private:
62     DISALLOW_COPY_AND_ASSIGN(StorageInterface);
63   };
64 
PrefsBase(StorageInterface * storage)65   explicit PrefsBase(StorageInterface* storage) : storage_(storage) {}
66 
67   // PrefsInterface methods.
68   bool GetString(const std::string& key, std::string* value) const override;
69   bool SetString(const std::string& key, const std::string& value) override;
70   bool GetInt64(const std::string& key, int64_t* value) const override;
71   bool SetInt64(const std::string& key, const int64_t value) override;
72   bool GetBoolean(const std::string& key, bool* value) const override;
73   bool SetBoolean(const std::string& key, const bool value) override;
74 
75   bool Exists(const std::string& key) const override;
76   bool Delete(const std::string& key) override;
77 
78   bool GetSubKeys(const std::string& ns,
79                   std::vector<std::string>* keys) const override;
80 
81   void AddObserver(const std::string& key,
82                    ObserverInterface* observer) override;
83   void RemoveObserver(const std::string& key,
84                       ObserverInterface* observer) override;
85 
86  private:
87   // The registered observers watching for changes.
88   std::map<std::string, std::vector<ObserverInterface*>> observers_;
89 
90   // The concrete implementation of the storage used for the keys.
91   StorageInterface* storage_;
92 
93   DISALLOW_COPY_AND_ASSIGN(PrefsBase);
94 };
95 
96 // Implements a preference store by storing the value associated with
97 // a key in a separate file named after the key under a preference
98 // store directory.
99 
100 class Prefs : public PrefsBase {
101  public:
Prefs()102   Prefs() : PrefsBase(&file_storage_) {}
103 
104   // Initializes the store by associating this object with |prefs_dir|
105   // as the preference store directory. Returns true on success, false
106   // otherwise.
107   bool Init(const base::FilePath& prefs_dir);
108 
109  private:
110   FRIEND_TEST(PrefsTest, GetFileNameForKey);
111   FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
112   FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
113 
114   class FileStorage : public PrefsBase::StorageInterface {
115    public:
116     FileStorage() = default;
117 
118     bool Init(const base::FilePath& prefs_dir);
119 
120     // PrefsBase::StorageInterface overrides.
121     bool GetKey(const std::string& key, std::string* value) const override;
122     bool GetSubKeys(const std::string& ns,
123                     std::vector<std::string>* keys) const override;
124     bool SetKey(const std::string& key, const std::string& value) override;
125     bool KeyExists(const std::string& key) const override;
126     bool DeleteKey(const std::string& key) override;
127 
128    private:
129     FRIEND_TEST(PrefsTest, GetFileNameForKey);
130     FRIEND_TEST(PrefsTest, GetFileNameForKeyBadCharacter);
131     FRIEND_TEST(PrefsTest, GetFileNameForKeyEmpty);
132 
133     // Sets |filename| to the full path to the file containing the data
134     // associated with |key|. Returns true on success, false otherwise.
135     bool GetFileNameForKey(const std::string& key,
136                            base::FilePath* filename) const;
137 
138     // Preference store directory.
139     base::FilePath prefs_dir_;
140   };
141 
142   // The concrete file storage implementation.
143   FileStorage file_storage_;
144 
145   DISALLOW_COPY_AND_ASSIGN(Prefs);
146 };
147 
148 // Implements a preference store in memory. The stored values are lost when the
149 // object is destroyed.
150 
151 class MemoryPrefs : public PrefsBase {
152  public:
MemoryPrefs()153   MemoryPrefs() : PrefsBase(&mem_storage_) {}
154 
155  private:
156   class MemoryStorage : public PrefsBase::StorageInterface {
157    public:
158     MemoryStorage() = default;
159 
160     // PrefsBase::StorageInterface overrides.
161     bool GetKey(const std::string& key, std::string* value) const override;
162     bool GetSubKeys(const std::string& ns,
163                     std::vector<std::string>* keys) const override;
164     bool SetKey(const std::string& key, const std::string& value) override;
165     bool KeyExists(const std::string& key) const override;
166     bool DeleteKey(const std::string& key) override;
167 
168    private:
169     // The std::map holding the values in memory.
170     std::map<std::string, std::string> values_;
171   };
172 
173   // The concrete memory storage implementation.
174   MemoryStorage mem_storage_;
175 
176   DISALLOW_COPY_AND_ASSIGN(MemoryPrefs);
177 };
178 }  // namespace chromeos_update_engine
179 
180 #endif  // UPDATE_ENGINE_COMMON_PREFS_H_
181