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 SHILL_PROFILE_H_
18 #define SHILL_PROFILE_H_
19 
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include <base/files/file_path.h>
26 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
27 
28 #include "shill/event_dispatcher.h"
29 #include "shill/property_store.h"
30 #include "shill/refptr_types.h"
31 
32 namespace base {
33 
34 class FilePath;
35 
36 }  // namespace base
37 
38 namespace shill {
39 
40 class ControlInterface;
41 class Error;
42 class Manager;
43 class Metrics;
44 class ProfileAdaptorInterface;
45 class StoreInterface;
46 
47 #if !defined(DISABLE_WIFI)
48 class WiFiProvider;
49 #endif  // DISABLE_WIFI
50 
51 class Profile : public base::RefCounted<Profile> {
52  public:
53   enum InitStorageOption {
54     kOpenExisting,
55     kCreateNew,
56     kCreateOrOpenExisting
57   };
58   struct Identifier {
IdentifierIdentifier59     Identifier() {}
IdentifierIdentifier60     explicit Identifier(const std::string& i) : identifier(i) {}
IdentifierIdentifier61     Identifier(const std::string& u, const std::string& i)
62         : user(u),
63           identifier(i) {
64     }
65     std::string user;  // Empty for global.
66     std::string identifier;
67     std::string user_hash;
68   };
69 
70   // Path to the cached list of inserted user profiles to be loaded at
71   // startup.
72   static const char kUserProfileListPathname[];
73 
74   Profile(ControlInterface* control_interface,
75           Metrics* metrics,
76           Manager* manager,
77           const Identifier& name,
78           const base::FilePath& storage_directory,
79           bool connect_to_rpc);
80 
81   virtual ~Profile();
82 
83   // Set up persistent storage for this Profile.
84   bool InitStorage(InitStorageOption storage_option,
85                    Error* error);
86 
87   // Set up stub storage for this Profile. The data will NOT be
88   // persisted. In most cases, you should prefer InitStorage.
89   void InitStubStorage();
90 
91   // Remove the persistent storage for this Profile.  It is an error to
92   // do so while the underlying storage is open via InitStorage() or
93   // set_storage().
94   bool RemoveStorage(Error* error);
95 
96   virtual std::string GetFriendlyName();
97 
98   virtual std::string GetRpcIdentifier();
99 
mutable_store()100   PropertyStore* mutable_store() { return &store_; }
store()101   const PropertyStore& store() const { return store_; }
102 
103   // Set the storage inteface.  This is used for testing purposes.  It
104   // takes ownership of |storage|.
105   void set_storage(StoreInterface* storage);
106 
107   // Begin managing the persistence of |service|.
108   // Returns true if |service| is new to this profile and was added,
109   // false if the |service| already existed.
110   virtual bool AdoptService(const ServiceRefPtr& service);
111 
112   // Cease managing the persistence of the Service |service|.
113   // Returns true if |service| was found and abandoned, or not found.
114   // Returns false if can't be abandoned.
115   virtual bool AbandonService(const ServiceRefPtr& service);
116 
117   // Clobbers persisted notion of |service| with data from |service|.
118   // Returns true if |service| was found and updated, false if not found.
119   virtual bool UpdateService(const ServiceRefPtr& service);
120 
121   // Ask |service| if it can configure itself from the profile.  If it can,
122   // ask |service| to perform the configuration and return true.  If not,
123   // return false.
124   virtual bool LoadService(const ServiceRefPtr& service);
125 
126   // Perform LoadService() on |service|.  If this succeeds, change
127   // the service to point at this profile and return true.  If not, return
128   // false.
129   virtual bool ConfigureService(const ServiceRefPtr& service);
130 
131   // Allow the device to configure itself from this profile.  Returns
132   // true if the device succeeded in finding its configuration.  If not,
133   // return false.
134   virtual bool ConfigureDevice(const DeviceRefPtr& device);
135 
136   // Remove a named entry from the profile.  This includes detaching
137   // any service that uses this profile entry.
138   virtual void DeleteEntry(const std::string& entry_name, Error* error);
139 
140   // Return a service configured from the given profile entry.
141   // Callers must not register the returned service with the Manager or connect
142   // it since it might not be in the provider's service list.
143   virtual ServiceRefPtr GetServiceFromEntry(const std::string& entry_name,
144                                             Error* error);
145 
146   // Return whether |service| can configure itself from the profile.
147   bool ContainsService(const ServiceConstRefPtr& service);
148 
149   std::vector<std::string> EnumerateAvailableServices(Error* error);
150   std::vector<std::string> EnumerateEntries(Error* error);
151 
152   // Clobbers persisted notion of |device| with data from |device|. Returns true
153   // if |device| was found and updated, false otherwise. The base implementation
154   // always returns false -- currently devices are persisted only in
155   // DefaultProfile.
156   virtual bool UpdateDevice(const DeviceRefPtr& device);
157 
158 #if !defined(DISABLE_WIFI)
159   // Clobbers persisted notion of |wifi_provider| with data from
160   // |wifi_provider|. Returns true if |wifi_provider| was found and updated,
161   // false otherwise. The base implementation always returns false -- currently
162   // wifi_provider is persisted only in DefaultProfile.
163   virtual bool UpdateWiFiProvider(const WiFiProvider& wifi_provider);
164 #endif  // DISABLE_WIFI
165 
166   // Write all in-memory state to disk via |storage_|.
167   virtual bool Save();
168 
169   // Parses a profile identifier. There're two acceptable forms of the |raw|
170   // identifier: "identifier" and "~user/identifier". Both "user" and
171   // "identifier" must be suitable for use in a D-Bus object path. Returns true
172   // on success.
173   static bool ParseIdentifier(const std::string& raw, Identifier* parsed);
174 
175   // Returns the composite string identifier for a profile, as would have
176   // been used in an argument to Manager::PushProfile() in creating this
177   // profile.  It returns a string in the form "identifier", or
178   // "~user/identifier" depending on whether this profile has a user
179   // component.
180   static std::string IdentifierToString(const Identifier& name);
181 
182   // Load a list of user profile identifiers from a cache file |path|.
183   // The profiles themselves are not loaded.
184   static std::vector<Identifier> LoadUserProfileList(
185       const base::FilePath& path);
186 
187   // Save a list of user profile identifiers |profiles| to a cache file |path|.
188   // Returns true if successful, false otherwise.
189   static bool SaveUserProfileList(const base::FilePath& path,
190                                   const std::vector<ProfileRefPtr>& profiles);
191 
192   // Returns whether |name| matches this Profile's |name_|.
193   virtual bool MatchesIdentifier(const Identifier& name) const;
194 
195   // Returns the username component of the profile identifier.
GetUser()196   const std::string& GetUser() const { return name_.user; }
197 
198   // Returns the user_hash component of the profile identifier.
GetUserHash()199   const std::string& GetUserHash() const { return name_.user_hash; }
200 
GetStorage()201   virtual StoreInterface* GetStorage() {
202     return storage_.get();
203   }
204 
205   // Returns a read-only copy of the backing storage of the profile.
GetConstStorage()206   virtual const StoreInterface* GetConstStorage() const {
207     return storage_.get();
208   }
209 
IsDefault()210   virtual bool IsDefault() const { return false; }
211 
212  protected:
213   // Returns the persistent store file path for a Profile with the
214   // given |storage_dir| and |profile_name|. Provided as a static
215   // method, so that tests can use this logic without having to
216   // instantiate a Profile.
217   static base::FilePath GetFinalStoragePath(
218       const base::FilePath& storage_dir,
219       const Identifier& profile_name);
220 
metrics()221   Metrics* metrics() const { return metrics_; }
manager()222   Manager* manager() const { return manager_; }
storage()223   StoreInterface* storage() { return storage_.get(); }
persistent_profile_path()224   const base::FilePath& persistent_profile_path() {
225     return persistent_profile_path_;
226   }
set_persistent_profile_path(const base::FilePath & path)227   void set_persistent_profile_path(const base::FilePath& path) {
228     persistent_profile_path_ = path;
229   }
230 
231  private:
232   friend class ManagerTest;
233   friend class ProfileAdaptorInterface;
234   FRIEND_TEST(ManagerTest, CreateDuplicateProfileWithMissingKeyfile);
235   FRIEND_TEST(ManagerTest, RemoveProfile);
236   FRIEND_TEST(ProfileTest, DeleteEntry);
237   FRIEND_TEST(ProfileTest, GetStoragePath);
238   FRIEND_TEST(ProfileTest, IsValidIdentifierToken);
239   FRIEND_TEST(ProfileTest, GetServiceFromEntry);
240 
241   static bool IsValidIdentifierToken(const std::string& token);
242 
243   void HelpRegisterConstDerivedStrings(
244       const std::string& name,
245       Strings(Profile::*get)(Error* error));
246 
247   // Data members shared with subclasses via getter/setters above in the
248   // protected: section
249   Metrics* metrics_;
250   Manager* manager_;
251   ControlInterface* control_interface_;
252   base::FilePath persistent_profile_path_;
253 
254   // Shared with |adaptor_| via public getter.
255   PropertyStore store_;
256 
257   // Properties to be gotten via PropertyStore calls.
258   Identifier name_;
259 
260   // Allows this profile to be backed with on-disk storage.
261   std::unique_ptr<StoreInterface> storage_;
262 
263   std::unique_ptr<ProfileAdaptorInterface> adaptor_;
264 
265   DISALLOW_COPY_AND_ASSIGN(Profile);
266 };
267 
268 }  // namespace shill
269 
270 #endif  // SHILL_PROFILE_H_
271