shill: Add uint64 properties

This is a fairly minimal addition, since we will only need
read-only derived types.

BUG=chromium-os:31584
TEST=New unit tests; list-devices on a real machine

Change-Id: I7b65224ae329443066f563b620b379f29006f8a0
Reviewed-on: https://gerrit.chromium.org/gerrit/27157
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
diff --git a/accessor_interface.h b/accessor_interface.h
index 527204c..50dab1e 100644
--- a/accessor_interface.h
+++ b/accessor_interface.h
@@ -75,6 +75,7 @@
 typedef std::tr1::shared_ptr<AccessorInterface<uint8> > Uint8Accessor;
 typedef std::tr1::shared_ptr<AccessorInterface<uint16> > Uint16Accessor;
 typedef std::tr1::shared_ptr<AccessorInterface<uint32> > Uint32Accessor;
+typedef std::tr1::shared_ptr<AccessorInterface<uint64> > Uint64Accessor;
 
 }  // namespace shill
 
diff --git a/dbus_adaptor.cc b/dbus_adaptor.cc
index ae7064d..0cf97b8 100644
--- a/dbus_adaptor.cc
+++ b/dbus_adaptor.cc
@@ -76,6 +76,8 @@
     store->SetUint16Property(name, value.reader().get_uint16(), &e);
   else if (DBusAdaptor::IsUint32(value.signature()))
     store->SetUint32Property(name, value.reader().get_uint32(), &e);
+  else if (DBusAdaptor::IsUint64(value.signature()))
+    store->SetUint64Property(name, value.reader().get_uint64(), &e);
   else if (DBusAdaptor::IsKeyValueStore(value.signature())) {
     SLOG(DBus, 1) << " can't yet handle setting type " << value.signature();
     e.Populate(Error::kInternalError);
@@ -192,6 +194,13 @@
     }
   }
   {
+    ReadablePropertyConstIterator<uint64> it = store.GetUint64PropertiesIter();
+    for ( ; !it.AtEnd(); it.Advance()) {
+      SLOG(DBus, 5) << __func__ << " serializing uint64 " << it.Key();
+      (*out)[it.Key()] = Uint64ToVariant(it.value());
+    }
+  }
+  {
     ReadablePropertyConstIterator<RpcIdentifier> it =
         store.GetRpcIdentifierPropertiesIter();
     for ( ; !it.AtEnd(); it.Advance()) {
@@ -369,6 +378,13 @@
 }
 
 // static
+::DBus::Variant DBusAdaptor::Uint64ToVariant(uint64 value) {
+  ::DBus::Variant v;
+  v.writer().append_uint64(value);
+  return v;
+}
+
+// static
 bool DBusAdaptor::IsBool(::DBus::Signature signature) {
   return signature == ::DBus::type<bool>::sig();
 }
@@ -434,6 +450,11 @@
 }
 
 // static
+bool DBusAdaptor::IsUint64(::DBus::Signature signature) {
+  return signature == ::DBus::type<uint64>::sig();
+}
+
+// static
 bool DBusAdaptor::IsKeyValueStore(::DBus::Signature signature) {
   return signature == ::DBus::type<map<string, ::DBus::Variant> >::sig();
 }
diff --git a/dbus_adaptor.h b/dbus_adaptor.h
index c43b080..1288a33 100644
--- a/dbus_adaptor.h
+++ b/dbus_adaptor.h
@@ -72,6 +72,7 @@
   static ::DBus::Variant StringsToVariant(const Strings &value);
   static ::DBus::Variant Uint16ToVariant(uint16 value);
   static ::DBus::Variant Uint32ToVariant(uint32 value);
+  static ::DBus::Variant Uint64ToVariant(uint64 value);
 
   static bool IsBool(::DBus::Signature signature);
   static bool IsByte(::DBus::Signature signature);
@@ -86,6 +87,7 @@
   static bool IsStrings(::DBus::Signature signature);
   static bool IsUint16(::DBus::Signature signature);
   static bool IsUint32(::DBus::Signature signature);
+  static bool IsUint64(::DBus::Signature signature);
   static bool IsKeyValueStore(::DBus::Signature signature);
 
  protected:
diff --git a/dbus_adaptor_unittest.cc b/dbus_adaptor_unittest.cc
index 5b15b67..70a282b 100644
--- a/dbus_adaptor_unittest.cc
+++ b/dbus_adaptor_unittest.cc
@@ -42,6 +42,7 @@
         ex_byte_(0xff),
         ex_uint16_(65535),
         ex_uint32_(2000000),
+        ex_uint64_(8589934591LL),
         ex_int16_(-32768),
         ex_int32_(-65536),
         ex_path_("/"),
@@ -56,6 +57,7 @@
         strings_v_(DBusAdaptor::StringsToVariant(ex_strings_)),
         uint16_v_(DBusAdaptor::Uint16ToVariant(ex_uint16_)),
         uint32_v_(DBusAdaptor::Uint32ToVariant(ex_uint32_)),
+        uint64_v_(DBusAdaptor::Uint64ToVariant(ex_uint64_)),
         device_(new MockDevice(control_interface(),
                                dispatcher(),
                                metrics(),
@@ -85,6 +87,7 @@
   ByteArrays ex_bytearrays_;
   uint16 ex_uint16_;
   uint32 ex_uint32_;
+  uint64 ex_uint64_;
   int16 ex_int16_;
   int32 ex_int32_;
   ::DBus::Path ex_path_;
@@ -107,6 +110,7 @@
   ::DBus::Variant strings_v_;
   ::DBus::Variant uint16_v_;
   ::DBus::Variant uint32_v_;
+  ::DBus::Variant uint64_v_;
 
   DeviceRefPtr device_;
   ServiceRefPtr service_;
@@ -130,6 +134,9 @@
   EXPECT_EQ(0, PropertyStoreTest::kUint32V.reader().get_uint32());
   EXPECT_EQ(ex_uint32_, uint32_v_.reader().get_uint32());
 
+  EXPECT_EQ(0, PropertyStoreTest::kUint64V.reader().get_uint64());
+  EXPECT_EQ(ex_uint64_, uint64_v_.reader().get_uint64());
+
   EXPECT_EQ(0, PropertyStoreTest::kInt32V.reader().get_int32());
   EXPECT_EQ(ex_int32_, int32_v_.reader().get_int32());
 
@@ -158,6 +165,7 @@
   EXPECT_TRUE(DBusAdaptor::IsStrings(strings_v_.signature()));
   EXPECT_TRUE(DBusAdaptor::IsUint16(uint16_v_.signature()));
   EXPECT_TRUE(DBusAdaptor::IsUint32(uint32_v_.signature()));
+  EXPECT_TRUE(DBusAdaptor::IsUint64(uint64_v_.signature()));
 
   EXPECT_FALSE(DBusAdaptor::IsBool(byte_v_.signature()));
   EXPECT_FALSE(DBusAdaptor::IsStrings(string_v_.signature()));
@@ -165,7 +173,7 @@
 
 TEST_F(DBusAdaptorTest, SetProperty) {
   MockPropertyStore store;
-  ::DBus::Error e1, e2, e3, e4, e5, e6, e7, e8, e9, e10;
+  ::DBus::Error e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11;
 
   EXPECT_CALL(store, Contains(_)).WillRepeatedly(Return(true));
   EXPECT_CALL(store, SetBoolProperty("", _, _)).WillOnce(Return(true));
@@ -180,6 +188,7 @@
   EXPECT_CALL(store, SetUint8Property("", _, _)).WillOnce(Return(true));
   EXPECT_CALL(store, SetUint16Property("", _, _)).WillOnce(Return(true));
   EXPECT_CALL(store, SetUint32Property("", _, _)).WillOnce(Return(true));
+  EXPECT_CALL(store, SetUint64Property("", _, _)).WillOnce(Return(true));
 
   string string_path("/false/path");
   ::DBus::Path path(string_path);
@@ -195,8 +204,9 @@
   EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", int32_v_, &e6));
   EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", uint16_v_, &e7));
   EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", uint32_v_, &e8));
-  EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", stringmap_v_, &e9));
-  EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", byte_v_, &e10));
+  EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", uint64_v_, &e9));
+  EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", stringmap_v_, &e10));
+  EXPECT_TRUE(DBusAdaptor::SetProperty(&store, "", byte_v_, &e11));
 }
 
 void SetError(const string &/*name*/, Error *error) {
diff --git a/mock_property_store.h b/mock_property_store.h
index d7f23f8..c0b8984 100644
--- a/mock_property_store.h
+++ b/mock_property_store.h
@@ -35,6 +35,7 @@
   MOCK_METHOD3(SetUint8Property, bool(const std::string&, uint8, Error*));
   MOCK_METHOD3(SetUint16Property, bool(const std::string&, uint16, Error*));
   MOCK_METHOD3(SetUint32Property, bool(const std::string&, uint32, Error*));
+  MOCK_METHOD3(SetUint64Property, bool(const std::string&, uint64, Error*));
   MOCK_METHOD2(ClearProperty, bool(const std::string&, Error*));
 
  private:
diff --git a/property_store.cc b/property_store.cc
index 933be70..36c3ce6 100644
--- a/property_store.cc
+++ b/property_store.cc
@@ -38,6 +38,7 @@
           ContainsKey(uint8_properties_, prop) ||
           ContainsKey(uint16_properties_, prop) ||
           ContainsKey(uint32_properties_, prop) ||
+          ContainsKey(uint64_properties_, prop) ||
           ContainsKey(rpc_identifier_properties_, prop) ||
           ContainsKey(rpc_identifiers_properties_, prop));
 }
@@ -97,6 +98,12 @@
   return SetProperty(name, value, error, uint32_properties_, "a uint32");
 }
 
+bool PropertyStore::SetUint64Property(const string &name,
+                                      uint64 value,
+                                      Error *error) {
+  return SetProperty(name, value, error, uint64_properties_, "a uint64");
+}
+
 bool PropertyStore::SetRpcIdentifierProperty(const string &name,
                                              const RpcIdentifier &value,
                                              Error *error) {
@@ -129,6 +136,8 @@
     uint16_properties_[name]->Clear(error);
   } else if (ContainsKey(uint32_properties_, name)) {
     uint32_properties_[name]->Clear(error);
+  } else if (ContainsKey(uint64_properties_, name)) {
+    uint64_properties_[name]->Clear(error);
   } else if (ContainsKey(rpc_identifier_properties_, name)) {
     rpc_identifier_properties_[name]->Clear(error);
   } else if (ContainsKey(rpc_identifiers_properties_, name)) {
@@ -209,6 +218,11 @@
   return ReadablePropertyConstIterator<uint32>(uint32_properties_);
 }
 
+ReadablePropertyConstIterator<uint64> PropertyStore::GetUint64PropertiesIter()
+    const {
+  return ReadablePropertyConstIterator<uint64>(uint64_properties_);
+}
+
 void PropertyStore::RegisterBool(const string &name, bool *prop) {
   DCHECK(!Contains(name) || ContainsKey(bool_properties_, name))
       << "(Already registered " << name << ")";
@@ -477,6 +491,13 @@
   uint16_properties_[name] = acc;
 }
 
+void PropertyStore::RegisterDerivedUint64(const string &name,
+                                          const Uint64Accessor &acc) {
+  DCHECK(!Contains(name) || ContainsKey(uint64_properties_, name))
+      << "(Already registered " << name << ")";
+  uint64_properties_[name] = acc;
+}
+
 // private methods
 
 template <class V>
diff --git a/property_store.h b/property_store.h
index 51576e1..829dcc4 100644
--- a/property_store.h
+++ b/property_store.h
@@ -68,6 +68,10 @@
                                  uint32 value,
                                  Error *error);
 
+  virtual bool SetUint64Property(const std::string &name,
+                                 uint64 value,
+                                 Error *error);
+
   virtual bool SetRpcIdentifierProperty(const std::string &name,
                                         const RpcIdentifier &value,
                                         Error *error);
@@ -109,6 +113,7 @@
   ReadablePropertyConstIterator<uint8> GetUint8PropertiesIter() const;
   ReadablePropertyConstIterator<uint16> GetUint16PropertiesIter() const;
   ReadablePropertyConstIterator<uint32> GetUint32PropertiesIter() const;
+  ReadablePropertyConstIterator<uint64> GetUint64PropertiesIter() const;
 
   // Methods for registering a property.
   //
@@ -172,6 +177,8 @@
                               const StringsAccessor &accessor);
   void RegisterDerivedUint16(const std::string &name,
                              const Uint16Accessor &accessor);
+  void RegisterDerivedUint64(const std::string &name,
+                             const Uint64Accessor &accessor);
 
  private:
   template <class V>
@@ -197,6 +204,7 @@
   std::map<std::string, Uint8Accessor> uint8_properties_;
   std::map<std::string, Uint16Accessor> uint16_properties_;
   std::map<std::string, Uint32Accessor> uint32_properties_;
+  std::map<std::string, Uint64Accessor> uint64_properties_;
 
   DISALLOW_COPY_AND_ASSIGN(PropertyStore);
 };
diff --git a/property_store_unittest.cc b/property_store_unittest.cc
index 15039fc..2256ff3 100644
--- a/property_store_unittest.cc
+++ b/property_store_unittest.cc
@@ -60,6 +60,9 @@
 // static
 const ::DBus::Variant PropertyStoreTest::kUint32V =
     DBusAdaptor::Uint32ToVariant(0);
+// static
+const ::DBus::Variant PropertyStoreTest::kUint64V =
+    DBusAdaptor::Uint64ToVariant(0);
 
 PropertyStoreTest::PropertyStoreTest()
     : internal_error_(Error::GetName(Error::kInternalError)),
@@ -101,7 +104,8 @@
            PropertyStoreTest::kStringmapV,
            PropertyStoreTest::kStringsV,
            PropertyStoreTest::kUint16V,
-           PropertyStoreTest::kUint32V));
+           PropertyStoreTest::kUint32V,
+           PropertyStoreTest::kUint64V));
 
 template <typename T>
 class PropertyStoreTypedTest : public PropertyStoreTest {
diff --git a/property_store_unittest.h b/property_store_unittest.h
index cb52996..657886d 100644
--- a/property_store_unittest.h
+++ b/property_store_unittest.h
@@ -44,6 +44,7 @@
   static const ::DBus::Variant kStringsV;
   static const ::DBus::Variant kUint16V;
   static const ::DBus::Variant kUint32V;
+  static const ::DBus::Variant kUint64V;
 
   PropertyStoreTest();
   virtual ~PropertyStoreTest();