[shill] Profiles need to own their own storage
We're moving to a model where we rely on the StoreInterface
implementation to maintain profile state, instead of managing
a list of Service objects manually. Thus, we need to allow
Profile to own its own StoreInterface.
BUG=chromium-os:17253
TEST=unit
Change-Id: Ie62462686ecf598efeac08a2d3180cd372430bb9
Reviewed-on: http://gerrit.chromium.org/gerrit/9916
Commit-Ready: Chris Masone <cmasone@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
diff --git a/profile.cc b/profile.cc
index 4111588..f65aa1b 100644
--- a/profile.cc
+++ b/profile.cc
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include <base/file_path.h>
#include <base/logging.h>
#include <base/stl_util-inl.h>
#include <base/string_util.h>
@@ -16,6 +17,7 @@
#include "shill/adaptor_interfaces.h"
#include "shill/control_interface.h"
+#include "shill/key_file_store.h"
#include "shill/manager.h"
#include "shill/property_accessor.h"
#include "shill/service.h"
@@ -57,6 +59,26 @@
DCHECK_EQ(services_.size(), 0);
}
+bool Profile::InitStorage(GLib *glib) {
+ FilePath final_path;
+ if (!GetStoragePath(&final_path)) {
+ PLOG(ERROR) <<
+ base::StringPrintf("Could not set up profile storage for %s:%s",
+ name_.user.c_str(), name_.identifier.c_str());
+ return false;
+ }
+ scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
+ storage->set_path(final_path);
+ if (!storage->Open()) {
+ PLOG(ERROR) <<
+ base::StringPrintf("Could not open profile storage for %s:%s",
+ name_.user.c_str(), name_.identifier.c_str());
+ return false;
+ }
+ set_storage(storage.release());
+ return true;
+}
+
string Profile::GetFriendlyName() {
return (name_.user.empty() ? "" : name_.user + "/") + name_.identifier;
}
@@ -65,6 +87,10 @@
return adaptor_->GetRpcIdentifier();
}
+void Profile::set_storage(StoreInterface *storage) {
+ storage_.reset(storage);
+}
+
bool Profile::AdoptService(const ServiceRefPtr &service) {
if (ContainsKey(services_, service->UniqueName()))
return false;
@@ -90,10 +116,11 @@
}
bool Profile::MergeService(const ServiceRefPtr &service) {
+ // TODO(cmasone): Make |service| just load itself from |store_|.
map<string, ServiceRefPtr>::iterator it;
for (it = services_.begin(); it != services_.end(); ++it) {
if (Mergeable(it->second, service))
- return true; // TODO(cmasone): Perform merge.
+ return true;
}
return false;
}
@@ -104,8 +131,8 @@
return NULL;
}
-void Profile::Finalize(StoreInterface *storage) {
- Save(storage);
+void Profile::Finalize() {
+ Save();
services_.clear();
}
@@ -150,12 +177,8 @@
return true;
}
-bool Profile::Load(StoreInterface */*storage*/) {
- return false;
-}
-
-bool Profile::Save(StoreInterface *storage) {
- return SaveServices(storage);
+bool Profile::Save() {
+ return SaveServices() && storage_->Flush();
}
bool Profile::GetStoragePath(FilePath *path) {
@@ -192,12 +215,12 @@
StringsAccessor(new CustomAccessor<Profile, Strings>(this, get, set)));
}
-bool Profile::SaveServices(StoreInterface *storage) {
+bool Profile::SaveServices() {
for (map<string, ServiceRefPtr>::iterator it = services_.begin();
it != services_.end();
++it) {
VLOG(1) << "Saving service named " << it->first;
- if (!it->second->Save(storage))
+ if (!it->second->Save(storage()))
return false;
}
return true;