[shill] Enable Device objects to persist themselves to disk

BUG=chromium-os:17254
TEST=unit

Change-Id: Ia00bc2658e0fe03e13e399d7afab81cc09aa0195
Reviewed-on: http://gerrit.chromium.org/gerrit/5309
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
diff --git a/device.cc b/device.cc
index fed0824..51615b9 100644
--- a/device.cc
+++ b/device.cc
@@ -12,6 +12,7 @@
 
 #include <base/logging.h>
 #include <base/memory/ref_counted.h>
+#include <base/stringprintf.h>
 #include <chromeos/dbus/service_constants.h>
 
 #include "shill/control_interface.h"
@@ -25,11 +26,20 @@
 #include "shill/rtnl_handler.h"
 #include "shill/service.h"
 #include "shill/shill_event.h"
+#include "shill/store_interface.h"
 
+using base::StringPrintf;
 using std::string;
 using std::vector;
 
 namespace shill {
+
+// static
+const char Device::kStoragePowered[] = "Powered";
+
+// static
+const char Device::kStorageIPConfigs[] = "IPConfigs";
+
 Device::Device(ControlInterface *control_interface,
                EventDispatcher *dispatcher,
                Manager *manager,
@@ -120,6 +130,12 @@
   return adaptor_->GetRpcIdentifier();
 }
 
+string Device::GetStorageIdentifier() {
+  string id = GetRpcIdentifier();
+  ControlInterface::RpcIdToStorageId(&id);
+  return id;
+}
+
 const string& Device::FriendlyName() const {
   return link_name_;
 }
@@ -128,6 +144,25 @@
   return unique_id_;
 }
 
+bool Device::Load(StoreInterface *storage) {
+  const string id = GetStorageIdentifier();
+  if (!storage->ContainsGroup(id)) {
+    LOG(WARNING) << "Device is not available in the persistent store: " << id;
+    return false;
+  }
+  storage->GetBool(id, kStoragePowered, &powered_);
+  // TODO(cmasone): What does it mean to load an IPConfig identifier??
+  return true;
+}
+
+bool Device::Save(StoreInterface *storage) {
+  const string id = GetStorageIdentifier();
+  storage->SetBool(id, kStoragePowered, powered_);
+  if (ipconfig_.get())
+    storage->SetString(id, kStorageIPConfigs, SerializeIPConfigsForStorage());
+  return true;
+}
+
 void Device::DestroyIPConfig() {
   if (ipconfig_.get()) {
     RTNLHandler::GetInstance()->RemoveInterfaceAddress(interface_index_,
@@ -164,6 +199,12 @@
   }
 }
 
+string Device::SerializeIPConfigsForStorage() {
+  return StringPrintf("%s:%s",
+                      ipconfig_->GetStorageIdentifier().c_str(),
+                      ipconfig_->type().c_str());
+}
+
 vector<string> Device::AvailableIPConfigs() {
   string id = (ipconfig_.get() ? ipconfig_->GetRpcIdentifier() : string());
   return vector<string>(1, id);