[shill] Enable objects to query an opaque RPC-system ID from Adaptors

This is needed for some properties.  For example Service has a property called Device, which is expected
to return a (in the current impl) a DBus path for the associated Device object.

BUG=chromium-os:16343
TEST=unit tests

Change-Id: I8bd32ab483331efabbfee05dbdeba045c7cb20da
Reviewed-on: http://gerrit.chromium.org/gerrit/3417
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
diff --git a/device.cc b/device.cc
index 428f985..447adde 100644
--- a/device.cc
+++ b/device.cc
@@ -21,6 +21,7 @@
 #include "shill/dhcp_provider.h"
 #include "shill/error.h"
 #include "shill/manager.h"
+#include "shill/property_accessor.h"
 #include "shill/refptr_types.h"
 #include "shill/rtnl_handler.h"
 #include "shill/service.h"
@@ -44,6 +45,9 @@
       running_(false) {
 
   RegisterConstString(flimflam::kAddressProperty, &hardware_address_);
+  RegisterDerivedString(flimflam::kDBusObjectProperty,
+                        &Device::GetRpcIdentifier,
+                        NULL);
   // TODO(cmasone): Chrome doesn't use this...does anyone?
   // RegisterConstString(flimflam::kInterfaceProperty, &link_name_);
   RegisterConstString(flimflam::kNameProperty, &link_name_);
@@ -53,7 +57,6 @@
 
   // TODO(cmasone): Add support for R/O properties that return DBus object paths
   // known_properties_.push_back(flimflam::kDBusConnectionProperty);
-  // known_properties_.push_back(flimflam::kDBusObjectProperty);
   // known_properties_.push_back(flimflam::kIPConfigsProperty);
   // known_properties_.push_back(flimflam::kNetworksProperty);
 
@@ -136,6 +139,10 @@
   return link_name();
 }
 
+string Device::GetRpcIdentifier() {
+  return adaptor_->GetRpcIdentifier();
+}
+
 void Device::DestroyIPConfig() {
   if (ipconfig_.get()) {
     RTNLHandler::GetInstance()->RemoveInterfaceAddress(interface_index_,
@@ -153,6 +160,13 @@
   return ipconfig_->RequestIP();
 }
 
+void Device::RegisterDerivedString(const string &name,
+                                    string(Device::*get)(void),
+                                    bool(Device::*set)(const string&)) {
+  string_properties_[name] =
+      StringAccessor(new CustomAccessor<Device, string>(this, get, set));
+}
+
 void Device::IPConfigUpdatedCallback(const IPConfigRefPtr &ipconfig,
                                      bool success) {
   // TODO(petkov): Use DeviceInfo to configure IP, etc. -- maybe through