libweave: Remove chromeos::Any from commands and state

Now PropValue can be constructed from base::Value.

BUG=brillo:1245, brillo:1246
TEST='FEATURES=test emerge-gizmo buffet'

Change-Id: I9a639aaf320499615da5f9735353d9e8ba9d4ad7
Reviewed-on: https://chromium-review.googlesource.com/289644
Trybot-Ready: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/libweave/include/weave/device.h b/libweave/include/weave/device.h
index 81289e9..c642945 100644
--- a/libweave/include/weave/device.h
+++ b/libweave/include/weave/device.h
@@ -11,7 +11,6 @@
 
 #include <base/files/file_path.h>
 #include <chromeos/errors/error.h>
-#include <chromeos/variant_dictionary.h>
 
 #include "weave/cloud.h"
 #include "weave/commands.h"
diff --git a/libweave/src/commands/command_instance_unittest.cc b/libweave/src/commands/command_instance_unittest.cc
index 7f00176..cc1759b 100644
--- a/libweave/src/commands/command_instance_unittest.cc
+++ b/libweave/src/commands/command_instance_unittest.cc
@@ -73,8 +73,9 @@
   StringPropType str_prop;
   IntPropType int_prop;
   ValueMap params;
-  params["phrase"] = str_prop.CreateValue(std::string("iPityDaFool"), nullptr);
-  params["volume"] = int_prop.CreateValue(5, nullptr);
+  params["phrase"] =
+      str_prop.CreateValue(base::StringValue{"iPityDaFool"}, nullptr);
+  params["volume"] = int_prop.CreateValue(base::FundamentalValue{5}, nullptr);
   CommandInstance instance{"robot.speak", CommandOrigin::kCloud,
                            dict_.FindCommand("robot.speak"), params};
 
diff --git a/libweave/src/commands/dbus_conversion.cc b/libweave/src/commands/dbus_conversion.cc
index bb98c45..d634081 100644
--- a/libweave/src/commands/dbus_conversion.cc
+++ b/libweave/src/commands/dbus_conversion.cc
@@ -220,129 +220,8 @@
   return nullptr;
 }
 
-bool ErrorMissingProperty(chromeos::ErrorPtr* error,
-                          const tracked_objects::Location& location,
-                          const char* param_name) {
-  chromeos::Error::AddToPrintf(error, location, errors::commands::kDomain,
-                               errors::commands::kPropertyMissing,
-                               "Required parameter missing: %s", param_name);
-  return false;
-}
-
 }  // namespace
 
-chromeos::Any PropValueToDBusVariant(const PropValue* value) {
-  if (value->GetType() == ValueType::Object)
-    return ObjectToDBusVariant(value->GetObject()->GetValue());
-
-  if (value->GetType() == ValueType::Array) {
-    const PropType* item_type =
-        value->GetPropType()->GetArray()->GetItemTypePtr();
-    return item_type->ConvertArrayToDBusVariant(value->GetArray()->GetValue());
-  }
-  return value->GetValueAsAny();
-}
-
-chromeos::VariantDictionary ObjectToDBusVariant(const ValueMap& object) {
-  chromeos::VariantDictionary dict;
-  for (const auto& pair : object) {
-    // Since we are inserting the elements from ValueMap which is
-    // a map, the keys are already sorted. So use the "end()" position as a hint
-    // for dict.insert() so the destination map can optimize its insertion
-    // time.
-    chromeos::Any prop = PropValueToDBusVariant(pair.second.get());
-    dict.emplace_hint(dict.end(), pair.first, std::move(prop));
-  }
-  return dict;
-}
-
-std::unique_ptr<const PropValue> PropValueFromDBusVariant(
-    const PropType* type,
-    const chromeos::Any& value,
-    chromeos::ErrorPtr* error) {
-  std::unique_ptr<const PropValue> result;
-  if (type->GetType() == ValueType::Array) {
-    // Special case for array types.
-    // We expect the |value| to contain std::vector<T>, while PropValue must use
-    // ValueVector instead. Do the conversion.
-    ValueVector arr;
-    const PropType* item_type = type->GetArray()->GetItemTypePtr();
-    if (item_type->ConvertDBusVariantToArray(value, &arr, error))
-      result = type->CreateValue(arr, error);
-  } else if (type->GetType() == ValueType::Object) {
-    // Special case for object types.
-    // We expect the |value| to contain chromeos::VariantDictionary, while
-    // PropValue must use ValueMap instead. Do the conversion.
-    if (!value.IsTypeCompatible<chromeos::VariantDictionary>()) {
-      type->GenerateErrorValueTypeMismatch(error);
-      return result;
-    }
-    CHECK(nullptr != type->GetObject()->GetObjectSchemaPtr())
-        << "An object type must have a schema defined for it";
-    ValueMap obj;
-    if (!ObjectFromDBusVariant(type->GetObject()->GetObjectSchemaPtr(),
-                               value.Get<chromeos::VariantDictionary>(), &obj,
-                               error)) {
-      return result;
-    }
-
-    result = type->CreateValue(std::move(obj), error);
-  } else {
-    result = type->CreateValue(value, error);
-  }
-
-  return result;
-}
-
-bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
-                           const chromeos::VariantDictionary& dict,
-                           ValueMap* obj,
-                           chromeos::ErrorPtr* error) {
-  std::set<std::string> keys_processed;
-  obj->clear();
-  // First go over all object parameters defined by type's object schema and
-  // extract the corresponding parameters from the source dictionary.
-  for (const auto& pair : object_schema->GetProps()) {
-    const PropValue* def_value = pair.second->GetDefaultValue();
-    auto it = dict.find(pair.first);
-    if (it != dict.end()) {
-      const PropType* prop_type = pair.second.get();
-      CHECK(prop_type) << "Value property type must be available";
-      auto prop_value = PropValueFromDBusVariant(prop_type, it->second, error);
-      if (!prop_value) {
-        chromeos::Error::AddToPrintf(
-            error, FROM_HERE, errors::commands::kDomain,
-            errors::commands::kInvalidPropValue,
-            "Invalid value for property '%s'", pair.first.c_str());
-        return false;
-      }
-      obj->emplace_hint(obj->end(), pair.first, std::move(prop_value));
-    } else if (def_value) {
-      obj->emplace_hint(obj->end(), pair.first, def_value->Clone());
-    } else {
-      ErrorMissingProperty(error, FROM_HERE, pair.first.c_str());
-      return false;
-    }
-    keys_processed.insert(pair.first);
-  }
-
-  // Make sure that we processed all the necessary properties and there weren't
-  // any extra (unknown) ones specified, unless the schema allows them.
-  if (!object_schema->GetExtraPropertiesAllowed()) {
-    for (const auto& pair : dict) {
-      if (keys_processed.find(pair.first) == keys_processed.end()) {
-        chromeos::Error::AddToPrintf(
-            error, FROM_HERE, errors::commands::kDomain,
-            errors::commands::kUnknownProperty, "Unrecognized property '%s'",
-            pair.first.c_str());
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
 // TODO(vitalybuka): Use in buffet_client.
 chromeos::VariantDictionary DictionaryToDBusVariantDictionary(
     const base::DictionaryValue& object) {
diff --git a/libweave/src/commands/dbus_conversion.h b/libweave/src/commands/dbus_conversion.h
index 5da2fef..6464cb0 100644
--- a/libweave/src/commands/dbus_conversion.h
+++ b/libweave/src/commands/dbus_conversion.h
@@ -14,29 +14,6 @@
 
 namespace weave {
 
-// Converts PropValue to Any in a format understood by D-Bus data serialization.
-// Has special handling for Object types where ValueMap are
-// converted to chromeos::VariantDictionary.
-chromeos::Any PropValueToDBusVariant(const PropValue* value);
-
-// Converts ValueMap to chromeos::VariantDictionary
-// with proper conversion of all nested properties.
-chromeos::VariantDictionary ObjectToDBusVariant(const ValueMap& object);
-
-// Converts D-Bus variant to PropValue.
-// Has special handling for Object types where chromeos::VariantDictionary
-// is converted to ValueMap.
-std::unique_ptr<const PropValue> PropValueFromDBusVariant(
-    const PropType* type,
-    const chromeos::Any& value,
-    chromeos::ErrorPtr* error);
-
-// Converts D-Bus variant to ObjectValue.
-bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
-                           const chromeos::VariantDictionary& dict,
-                           ValueMap* obj,
-                           chromeos::ErrorPtr* error);
-
 // Converts DictionaryValue to D-Bus variant dictionary.
 chromeos::VariantDictionary DictionaryToDBusVariantDictionary(
     const base::DictionaryValue& object);
diff --git a/libweave/src/commands/dbus_conversion_unittest.cc b/libweave/src/commands/dbus_conversion_unittest.cc
index 06e1718..28c423a 100644
--- a/libweave/src/commands/dbus_conversion_unittest.cc
+++ b/libweave/src/commands/dbus_conversion_unittest.cc
@@ -122,167 +122,6 @@
 
 }  // namespace
 
-TEST(DBusConversionTest, PropValueToDBusVariant) {
-  IntPropType int_type;
-  auto prop_value = int_type.CreateValue(5, nullptr);
-  EXPECT_EQ(5, PropValueToDBusVariant(prop_value.get()).Get<int>());
-
-  BooleanPropType bool_type;
-  prop_value = bool_type.CreateValue(true, nullptr);
-  EXPECT_TRUE(PropValueToDBusVariant(prop_value.get()).Get<bool>());
-
-  DoublePropType dbl_type;
-  prop_value = dbl_type.CreateValue(5.5, nullptr);
-  EXPECT_DOUBLE_EQ(5.5, PropValueToDBusVariant(prop_value.get()).Get<double>());
-
-  StringPropType str_type;
-  prop_value = str_type.CreateValue(std::string{"foo"}, nullptr);
-  EXPECT_EQ("foo", PropValueToDBusVariant(prop_value.get()).Get<std::string>());
-
-  ObjectPropType obj_type;
-  ASSERT_TRUE(obj_type.FromJson(
-      CreateDictionaryValue(
-          "{'properties':{'width':'integer','height':'integer'},"
-          "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}")
-          .get(),
-      nullptr, nullptr));
-  ValueMap obj{
-      {"width", int_type.CreateValue(10, nullptr)},
-      {"height", int_type.CreateValue(20, nullptr)},
-  };
-  prop_value = obj_type.CreateValue(obj, nullptr);
-  VariantDictionary dict =
-      PropValueToDBusVariant(prop_value.get()).Get<VariantDictionary>();
-  EXPECT_EQ(20, dict["height"].Get<int>());
-  EXPECT_EQ(10, dict["width"].Get<int>());
-
-  ArrayPropType arr_type;
-  arr_type.SetItemType(str_type.Clone());
-  ValueVector arr;
-  arr.push_back(str_type.CreateValue(std::string{"foo"}, nullptr));
-  arr.push_back(str_type.CreateValue(std::string{"bar"}, nullptr));
-  arr.push_back(str_type.CreateValue(std::string{"baz"}, nullptr));
-  prop_value = arr_type.CreateValue(arr, nullptr);
-  chromeos::Any any = PropValueToDBusVariant(prop_value.get());
-  ASSERT_TRUE(any.IsTypeCompatible<std::vector<std::string>>());
-  EXPECT_EQ((std::vector<std::string>{"foo", "bar", "baz"}),
-            any.Get<std::vector<std::string>>());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_Int) {
-  IntPropType int_type;
-  ASSERT_TRUE(int_type.FromJson(CreateDictionaryValue("{'enum':[1,2]}").get(),
-                                nullptr, nullptr));
-
-  auto prop_value = PropValueFromDBusVariant(&int_type, 1, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  EXPECT_EQ(1, prop_value->GetValueAsAny().Get<int>());
-
-  chromeos::ErrorPtr error;
-  prop_value = PropValueFromDBusVariant(&int_type, 5, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_Bool) {
-  BooleanPropType bool_type;
-  ASSERT_TRUE(bool_type.FromJson(CreateDictionaryValue("{'enum':[true]}").get(),
-                                 nullptr, nullptr));
-
-  auto prop_value = PropValueFromDBusVariant(&bool_type, true, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  EXPECT_TRUE(prop_value->GetValueAsAny().Get<bool>());
-
-  chromeos::ErrorPtr error;
-  prop_value = PropValueFromDBusVariant(&bool_type, false, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_Double) {
-  DoublePropType dbl_type;
-  ASSERT_TRUE(dbl_type.FromJson(CreateDictionaryValue("{'maximum':2.0}").get(),
-                                nullptr, nullptr));
-
-  auto prop_value = PropValueFromDBusVariant(&dbl_type, 1.0, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  EXPECT_DOUBLE_EQ(1.0, prop_value->GetValueAsAny().Get<double>());
-
-  chromeos::ErrorPtr error;
-  prop_value = PropValueFromDBusVariant(&dbl_type, 10.0, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_String) {
-  StringPropType str_type;
-  ASSERT_TRUE(str_type.FromJson(CreateDictionaryValue("{'minLength': 4}").get(),
-                                nullptr, nullptr));
-
-  auto prop_value =
-      PropValueFromDBusVariant(&str_type, std::string{"blah"}, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  EXPECT_EQ("blah", prop_value->GetValueAsAny().Get<std::string>());
-
-  chromeos::ErrorPtr error;
-  prop_value = PropValueFromDBusVariant(&str_type, std::string{"foo"}, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_Object) {
-  ObjectPropType obj_type;
-  ASSERT_TRUE(obj_type.FromJson(
-      CreateDictionaryValue(
-          "{'properties':{'width':'integer','height':'integer'},"
-          "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}")
-          .get(),
-      nullptr, nullptr));
-
-  VariantDictionary obj{
-      {"width", 100}, {"height", 200},
-  };
-  auto prop_value = PropValueFromDBusVariant(&obj_type, obj, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  auto value = prop_value->GetValueAsAny().Get<ValueMap>();
-  EXPECT_EQ(100, value["width"].get()->GetValueAsAny().Get<int>());
-  EXPECT_EQ(200, value["height"].get()->GetValueAsAny().Get<int>());
-
-  chromeos::ErrorPtr error;
-  obj["height"] = 20;
-  prop_value = PropValueFromDBusVariant(&obj_type, obj, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
-TEST(DBusConversionTest, PropValueFromDBusVariant_Array) {
-  ArrayPropType arr_type;
-  IntPropType int_type;
-  int_type.AddMinMaxConstraint(0, 100);
-  arr_type.SetItemType(int_type.Clone());
-  std::vector<int> data{0, 1, 1, 100};
-  auto prop_value = PropValueFromDBusVariant(&arr_type, data, nullptr);
-  ASSERT_NE(nullptr, prop_value.get());
-  auto arr = prop_value->GetValueAsAny().Get<ValueVector>();
-  ASSERT_EQ(4u, arr.size());
-  EXPECT_EQ(0, arr[0]->GetInt()->GetValue());
-  EXPECT_EQ(1, arr[1]->GetInt()->GetValue());
-  EXPECT_EQ(1, arr[2]->GetInt()->GetValue());
-  EXPECT_EQ(100, arr[3]->GetInt()->GetValue());
-
-  chromeos::ErrorPtr error;
-  data.push_back(-1);  // This value is out of bounds for |int_type|.
-  prop_value = PropValueFromDBusVariant(&arr_type, data, &error);
-  EXPECT_EQ(nullptr, prop_value.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-}
-
 TEST(DBusConversionTest, DictionaryToDBusVariantDictionary) {
   EXPECT_EQ((VariantDictionary{{"bool", true}}),
             ToDBus(*CreateDictionaryValue("{'bool': true}")));
diff --git a/libweave/src/commands/object_schema_unittest.cc b/libweave/src/commands/object_schema_unittest.cc
index d1c7269..018c28f 100644
--- a/libweave/src/commands/object_schema_unittest.cc
+++ b/libweave/src/commands/object_schema_unittest.cc
@@ -31,7 +31,8 @@
   std::vector<T> values;
   values.reserve(arr.size());
   for (const auto& prop_value : arr) {
-    values.push_back(prop_value->GetValueAsAny().Get<T>());
+    const auto& value = static_cast<const TypedValueBase<T>&>(*prop_value);
+    values.push_back(value.GetValue());
   }
   return values;
 }
@@ -153,12 +154,12 @@
 TEST(CommandSchema, IntPropType_CreateValue) {
   IntPropType prop;
   chromeos::ErrorPtr error;
-  auto val = prop.CreateValue(2, &error);
+  auto val = prop.CreateValue(base::FundamentalValue{2}, &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(2, val->GetValueAsAny().Get<int>());
+  EXPECT_EQ(2, val->GetValue());
 
-  val = prop.CreateValue("blah", &error);
+  val = prop.CreateValue(base::StringValue{"blah"}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
@@ -242,12 +243,12 @@
 TEST(CommandSchema, BoolPropType_CreateValue) {
   BooleanPropType prop;
   chromeos::ErrorPtr error;
-  auto val = prop.CreateValue(true, &error);
+  auto val = prop.CreateValue(base::FundamentalValue{true}, &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(val->GetValueAsAny().Get<bool>());
+  EXPECT_TRUE(val->GetValue());
 
-  val = prop.CreateValue("blah", &error);
+  val = prop.CreateValue(base::StringValue{"blah"}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
@@ -359,12 +360,12 @@
 TEST(CommandSchema, DoublePropType_CreateValue) {
   DoublePropType prop;
   chromeos::ErrorPtr error;
-  auto val = prop.CreateValue(2.0, &error);
+  auto val = prop.CreateValue(base::FundamentalValue{2.0}, &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_DOUBLE_EQ(2.0, val->GetValueAsAny().Get<double>());
+  EXPECT_DOUBLE_EQ(2.0, val->GetValue());
 
-  val = prop.CreateValue("blah", &error);
+  val = prop.CreateValue(base::StringValue{"blah"}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
@@ -484,12 +485,12 @@
 TEST(CommandSchema, StringPropType_CreateValue) {
   StringPropType prop;
   chromeos::ErrorPtr error;
-  auto val = prop.CreateValue(std::string{"blah"}, &error);
+  auto val = prop.CreateValue(base::StringValue{"blah"}, &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ("blah", val->GetValueAsAny().Get<std::string>());
+  EXPECT_EQ("blah", val->GetValue());
 
-  val = prop.CreateValue(4, &error);
+  val = prop.CreateValue(base::FundamentalValue{4}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
@@ -737,17 +738,18 @@
           .get(),
       nullptr, nullptr));
   ValueMap obj{
-      {"width", int_type.CreateValue(10, nullptr)},
-      {"height", int_type.CreateValue(20, nullptr)},
+      {"width", int_type.CreateValue(base::FundamentalValue{10}, nullptr)},
+      {"height", int_type.CreateValue(base::FundamentalValue{20}, nullptr)},
   };
 
   chromeos::ErrorPtr error;
-  auto val = prop.CreateValue(obj, &error);
+  auto val = prop.CreateValue(
+      *CreateDictionaryValue("{'width': 10, 'height': 20}"), &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(obj, val->GetValueAsAny().Get<ValueMap>());
+  EXPECT_EQ(obj, val->GetValue());
 
-  val = prop.CreateValue("blah", &error);
+  val = prop.CreateValue(base::StringValue{"blah"}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
@@ -866,40 +868,21 @@
   chromeos::ErrorPtr error;
   ValueVector arr;
 
-  auto val = prop.CreateValue(arr, &error);
+  auto val = prop.CreateValue(base::ListValue{}, &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(arr, val->GetValueAsAny().Get<ValueVector>());
+  EXPECT_EQ(arr, val->GetValue());
   EXPECT_JSON_EQ("[]", *val->ToJson());
 
-  IntPropType int_type;
-  ObjectPropType obj_type;
-  ASSERT_TRUE(obj_type.FromJson(
-      CreateDictionaryValue(
-          "{'properties':{'width':'integer','height':'integer'}}")
-          .get(),
-      nullptr, nullptr));
-  arr.push_back(obj_type.CreateValue(
-      ValueMap{
-          {"width", int_type.CreateValue(10, nullptr)},
-          {"height", int_type.CreateValue(20, nullptr)},
-      },
-      nullptr));
-  arr.push_back(obj_type.CreateValue(
-      ValueMap{
-          {"width", int_type.CreateValue(17, nullptr)},
-          {"height", int_type.CreateValue(18, nullptr)},
-      },
-      nullptr));
-
-  val = prop.CreateValue(arr, &error);
+  val = prop.CreateValue(
+      *CreateValue("[{'height':20,'width':10},{'width':17, 'height':18}]"),
+      &error);
   ASSERT_NE(nullptr, val.get());
   EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(arr, val->GetValueAsAny().Get<ValueVector>());
   EXPECT_JSON_EQ("[{'height':20,'width':10},{'height':18,'width':17}]",
                  *val->ToJson());
 
-  val = prop.CreateValue("blah", &error);
+  val = prop.CreateValue(base::StringValue{"blah"}, &error);
   EXPECT_EQ(nullptr, val.get());
   ASSERT_NE(nullptr, error.get());
   EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
diff --git a/libweave/src/commands/prop_constraints.h b/libweave/src/commands/prop_constraints.h
index 80ecbb9..098f97c 100644
--- a/libweave/src/commands/prop_constraints.h
+++ b/libweave/src/commands/prop_constraints.h
@@ -132,11 +132,12 @@
   // Implementation of Constraint::Validate().
   bool Validate(const PropValue& value,
                 chromeos::ErrorPtr* error) const override {
-    T v = value.GetValueAsAny().Get<T>();
-    if (v < this->limit_.value)
+    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
+    if (v < this->limit_.value) {
       return this->ReportErrorLessThan(
           error, chromeos::string_utils::ToString(v),
           chromeos::string_utils::ToString(this->limit_.value));
+    }
     return true;
   }
 
@@ -173,7 +174,7 @@
   // Implementation of Constraint::Validate().
   bool Validate(const PropValue& value,
                 chromeos::ErrorPtr* error) const override {
-    T v = value.GetValueAsAny().Get<T>();
+    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
     if (v > this->limit_.value)
       return this->ReportErrorGreaterThan(
           error, chromeos::string_utils::ToString(v),
diff --git a/libweave/src/commands/prop_types.cc b/libweave/src/commands/prop_types.cc
index a5db4cb..4ddfc00 100644
--- a/libweave/src/commands/prop_types.cc
+++ b/libweave/src/commands/prop_types.cc
@@ -11,7 +11,6 @@
 #include <base/json/json_writer.h>
 #include <base/logging.h>
 #include <base/values.h>
-#include <chromeos/any.h>
 #include <chromeos/strings/string_utils.h>
 
 #include "libweave/src/commands/object_schema.h"
@@ -239,11 +238,6 @@
   return val->FromJson(value, error);
 }
 
-bool PropType::ValidateValue(const chromeos::Any& value,
-                             chromeos::ErrorPtr* error) const {
-  return !!CreateValue(value, error);
-}
-
 bool PropType::ValidateConstraints(const PropValue& value,
                                    chromeos::ErrorPtr* error) const {
   for (const auto& pair : constraints_) {
@@ -309,14 +303,6 @@
   return std::unique_ptr<PropType>(prop);
 }
 
-bool PropType::GenerateErrorValueTypeMismatch(chromeos::ErrorPtr* error) const {
-  chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                               errors::commands::kTypeMismatch,
-                               "Unable to convert value to type '%s'",
-                               GetTypeAsString().c_str());
-  return false;
-}
-
 template <typename T>
 static std::unique_ptr<Constraint> LoadOneOfConstraint(
     const base::DictionaryValue* value,
@@ -596,36 +582,6 @@
   return true;
 }
 
-chromeos::Any ObjectPropType::ConvertArrayToDBusVariant(
-    const ValueVector& source) const {
-  std::vector<chromeos::VariantDictionary> result;
-  result.reserve(source.size());
-  for (const auto& prop_value : source) {
-    chromeos::Any dict = PropValueToDBusVariant(prop_value.get());
-    result.push_back(std::move(*dict.GetPtr<chromeos::VariantDictionary>()));
-  }
-  return result;
-}
-
-bool ObjectPropType::ConvertDBusVariantToArray(
-    const chromeos::Any& source,
-    ValueVector* result,
-    chromeos::ErrorPtr* error) const {
-  if (!source.IsTypeCompatible<std::vector<chromeos::VariantDictionary>>())
-    return GenerateErrorValueTypeMismatch(error);
-
-  const auto& source_array =
-      source.Get<std::vector<chromeos::VariantDictionary>>();
-  result->reserve(source_array.size());
-  for (const auto& value : source_array) {
-    auto prop_value = PropValueFromDBusVariant(this, value, error);
-    if (!prop_value)
-      return false;
-    result->push_back(std::move(prop_value));
-  }
-  return true;
-}
-
 void ObjectPropType::SetObjectSchema(
     std::unique_ptr<const ObjectSchema> schema) {
   object_schema_.value = std::move(schema);
diff --git a/libweave/src/commands/prop_types.h b/libweave/src/commands/prop_types.h
index 6b364f3..71de94d 100644
--- a/libweave/src/commands/prop_types.h
+++ b/libweave/src/commands/prop_types.h
@@ -13,10 +13,8 @@
 #include <utility>
 #include <vector>
 
-#include <chromeos/any.h>
 #include <chromeos/errors/error.h>
 
-#include "libweave/src/commands/dbus_conversion.h"
 #include "libweave/src/commands/prop_constraints.h"
 #include "libweave/src/commands/prop_values.h"
 
@@ -90,24 +88,6 @@
   // Creates an instance of associated value object, using the parameter
   // type as a factory class.
   virtual std::unique_ptr<PropValue> CreateValue() const = 0;
-  virtual std::unique_ptr<PropValue> CreateValue(
-      const chromeos::Any& val,
-      chromeos::ErrorPtr* error) const = 0;
-
-  // Converts an array of PropValue containing the values of the types described
-  // by this instance of PropType into an Any containing std::vector<T>, where
-  // T corresponds to the native representation of this PropType.
-  virtual chromeos::Any ConvertArrayToDBusVariant(
-      const ValueVector& source) const = 0;
-
-  // ConvertAnyToArray is the opposite of ConvertArrayToAny().
-  // Given an Any containing std::vector<T>, converts each value into the
-  // corresponding PropValue of type of this PropType and adds them to
-  // |result| array. If type conversion fails, this function returns false
-  // and specifies the error details in |error|.
-  virtual bool ConvertDBusVariantToArray(const chromeos::Any& source,
-                                         ValueVector* result,
-                                         chromeos::ErrorPtr* error) const = 0;
 
   // Saves the parameter type definition as a JSON object.
   // If |full_schema| is set to true, the full type definition is saved,
@@ -152,10 +132,6 @@
   // the |error| parameter.
   bool ValidateValue(const base::Value* value, chromeos::ErrorPtr* error) const;
 
-  // Similar to the above method, but uses Any as the value container.
-  bool ValidateValue(const chromeos::Any& value,
-                     chromeos::ErrorPtr* error) const;
-
   // Additional helper static methods to help with converting a type enum
   // value into a string and back.
   using TypeMap = std::vector<std::pair<ValueType, std::string>>;
@@ -185,10 +161,6 @@
   bool ValidateConstraints(const PropValue& value,
                            chromeos::ErrorPtr* error) const;
 
-  // Helper method to generate "type mismatch" error when creating a value
-  // from this type. Always returns false.
-  bool GenerateErrorValueTypeMismatch(chromeos::ErrorPtr* error) const;
-
  protected:
   // Specifies if this parameter definition is derived from a base
   // object schema.
@@ -222,44 +194,12 @@
     return std::unique_ptr<PropValue>{new Value{Clone()}};
   }
 
-  std::unique_ptr<PropValue> CreateValue(
-      const chromeos::Any& v,
-      chromeos::ErrorPtr* error) const override {
-    if (!v.IsTypeCompatible<T>()) {
-      GenerateErrorValueTypeMismatch(error);
+  std::unique_ptr<Value> CreateValue(const base::Value& value,
+                                     chromeos::ErrorPtr* error) const {
+    std::unique_ptr<Value> prop_value{new Value{Clone()}};
+    if (!prop_value->FromJson(&value, error))
       return nullptr;
-    }
-    std::unique_ptr<Value> value{new Value{Clone()}};
-    if (!value->SetValue(v.Get<T>(), error))
-      return nullptr;
-    return std::move(value);
-  }
-
-  chromeos::Any ConvertArrayToDBusVariant(
-      const ValueVector& source) const override {
-    std::vector<T> result;
-    result.reserve(source.size());
-    for (const auto& prop_value : source) {
-      result.push_back(PropValueToDBusVariant(prop_value.get()).Get<T>());
-    }
-    return result;
-  }
-
-  bool ConvertDBusVariantToArray(const chromeos::Any& source,
-                                 ValueVector* result,
-                                 chromeos::ErrorPtr* error) const override {
-    if (!source.IsTypeCompatible<std::vector<T>>())
-      return GenerateErrorValueTypeMismatch(error);
-
-    const auto& source_array = source.Get<std::vector<T>>();
-    result->reserve(source_array.size());
-    for (const auto& value : source_array) {
-      auto prop_value = PropValueFromDBusVariant(this, value, error);
-      if (!prop_value)
-        return false;
-      result->push_back(std::move(prop_value));
-    }
-    return true;
+    return prop_value;
   }
 
   bool ConstraintsFromJson(const base::DictionaryValue* value,
@@ -366,13 +306,6 @@
                             std::set<std::string>* processed_keys,
                             chromeos::ErrorPtr* error) override;
 
-  chromeos::Any ConvertArrayToDBusVariant(
-      const ValueVector& source) const override;
-
-  bool ConvertDBusVariantToArray(const chromeos::Any& source,
-                                 ValueVector* result,
-                                 chromeos::ErrorPtr* error) const override;
-
   // Returns a schema for Object-type parameter.
   inline const ObjectSchema* GetObjectSchemaPtr() const {
     return object_schema_.value.get();
diff --git a/libweave/src/commands/prop_values.cc b/libweave/src/commands/prop_values.cc
index abde3b7..813f9c6 100644
--- a/libweave/src/commands/prop_values.cc
+++ b/libweave/src/commands/prop_values.cc
@@ -12,8 +12,8 @@
     : type_{std::move(type)} {
 }
 
-PropValue::PropValue(const PropType* type_ptr) : type_{type_ptr->Clone()} {
-}
+PropValue::PropValue(const PropValue& other)
+    : PropValue{other.type_->Clone()} {}
 
 PropValue::~PropValue() {
 }
diff --git a/libweave/src/commands/prop_values.h b/libweave/src/commands/prop_values.h
index fa9963a..d50c1a4 100644
--- a/libweave/src/commands/prop_values.h
+++ b/libweave/src/commands/prop_values.h
@@ -9,7 +9,6 @@
 #include <memory>
 #include <string>
 
-#include <chromeos/any.h>
 #include <chromeos/errors/error.h>
 
 #include "libweave/src/commands/schema_utils.h"
@@ -85,11 +84,6 @@
 class PropValue {
  public:
   explicit PropValue(std::unique_ptr<const PropType> type);
-  // Special out-of-line constructor to help implement PropValue::Clone().
-  // That method needs to clone the underlying type but can't do this in this
-  // header file since PropType is just forward-declared (it needs PropValue
-  // fully defined in its own inner workings).
-  explicit PropValue(const PropType* type_ptr);
   virtual ~PropValue();
 
   // Gets the type of the value.
@@ -120,37 +114,34 @@
   virtual bool FromJson(const base::Value* value,
                         chromeos::ErrorPtr* error) = 0;
 
-  // Returns the contained C++ value as Any.
-  virtual chromeos::Any GetValueAsAny() const = 0;
-
   // Return the type definition of this value.
   const PropType* GetPropType() const { return type_.get(); }
   // Compares two values and returns true if they are equal.
   virtual bool IsEqual(const PropValue* value) const = 0;
 
  protected:
+  // Special out-of-line constructor to help implement PropValue::Clone().
+  // That method needs to clone the underlying type but can't do this in this
+  // header file since PropType is just forward-declared (it needs PropValue
+  // fully defined in its own inner workings).
+  explicit PropValue(const PropValue& other);
+
+ private:
   std::unique_ptr<const PropType> type_;
 };
 
 // A helper template base class for implementing value classes.
-template <typename Derived, typename T>
+template <typename T>
 class TypedValueBase : public PropValue {
  public:
   // To help refer to this base class from derived classes, define Base to
   // be this class.
-  using Base = TypedValueBase<Derived, T>;
-  // Expose the non-default constructor of the base class.
+  using Base = TypedValueBase<T>;
   using PropValue::PropValue;
 
   // Overrides from PropValue base class.
   ValueType GetType() const override { return GetValueType<T>(); }
 
-  std::unique_ptr<PropValue> Clone() const override {
-    std::unique_ptr<Derived> derived{new Derived{type_.get()}};
-    derived->value_ = value_;
-    return std::move(derived);
-  }
-
   std::unique_ptr<base::Value> ToJson() const override {
     return TypedValueToJson(value_);
   }
@@ -170,7 +161,6 @@
   }
 
   // Helper methods to get and set the C++ representation of the value.
-  chromeos::Any GetValueAsAny() const override { return value_; }
   const T& GetValue() const { return value_; }
   bool SetValue(T value, chromeos::ErrorPtr* error) {
     std::swap(value_, value);  // Backup.
@@ -181,11 +171,31 @@
   }
 
  protected:
+  explicit TypedValueBase(const TypedValueBase& other)
+      : PropValue(other), value_(other.value_) {}
+
+ private:
   T value_{};  // The value of the parameter in C++ data representation.
 };
 
+// A helper template base class for implementing value classes.
+template <typename Derived, typename T>
+class TypedValueWithClone : public TypedValueBase<T> {
+ public:
+  using Base = TypedValueWithClone<Derived, T>;
+
+  // Expose the custom constructor of the base class.
+  using TypedValueBase<T>::TypedValueBase;
+  using PropValue::GetPropType;
+
+  std::unique_ptr<PropValue> Clone() const override {
+    return std::unique_ptr<PropValue>{
+        new Derived{*static_cast<const Derived*>(this)}};
+  }
+};
+
 // Value of type Integer.
-class IntValue final : public TypedValueBase<IntValue, int> {
+class IntValue final : public TypedValueWithClone<IntValue, int> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   IntValue* GetInt() override { return this; }
@@ -193,7 +203,7 @@
 };
 
 // Value of type Number.
-class DoubleValue final : public TypedValueBase<DoubleValue, double> {
+class DoubleValue final : public TypedValueWithClone<DoubleValue, double> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   DoubleValue* GetDouble() override { return this; }
@@ -201,7 +211,7 @@
 };
 
 // Value of type String.
-class StringValue final : public TypedValueBase<StringValue, std::string> {
+class StringValue final : public TypedValueWithClone<StringValue, std::string> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   StringValue* GetString() override { return this; }
@@ -209,7 +219,7 @@
 };
 
 // Value of type Boolean.
-class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
+class BooleanValue final : public TypedValueWithClone<BooleanValue, bool> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   BooleanValue* GetBoolean() override { return this; }
@@ -217,7 +227,7 @@
 };
 
 // Value of type Object.
-class ObjectValue final : public TypedValueBase<ObjectValue, ValueMap> {
+class ObjectValue final : public TypedValueWithClone<ObjectValue, ValueMap> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   ObjectValue* GetObject() override { return this; }
@@ -225,7 +235,7 @@
 };
 
 // Value of type Array.
-class ArrayValue final : public TypedValueBase<ArrayValue, ValueVector> {
+class ArrayValue final : public TypedValueWithClone<ArrayValue, ValueVector> {
  public:
   using Base::Base;  // Expose the custom constructor of the base class.
   ArrayValue* GetArray() override { return this; }
diff --git a/libweave/src/commands/schema_utils_unittest.cc b/libweave/src/commands/schema_utils_unittest.cc
index 6924d3b..8acb1ee 100644
--- a/libweave/src/commands/schema_utils_unittest.cc
+++ b/libweave/src/commands/schema_utils_unittest.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include <base/values.h>
-#include <chromeos/variant_dictionary.h>
 #include <gtest/gtest.h>
 
 #include "libweave/src/commands/object_schema.h"
@@ -22,7 +21,6 @@
 
 using unittests::CreateDictionaryValue;
 using unittests::CreateValue;
-using chromeos::VariantDictionary;
 
 TEST(CommandSchemaUtils, TypedValueToJson_Scalar) {
   EXPECT_JSON_EQ("true", *TypedValueToJson(true));
@@ -54,8 +52,10 @@
   IntPropType int_type;
   ValueMap object;
 
-  object.insert(std::make_pair("width", int_type.CreateValue(640, nullptr)));
-  object.insert(std::make_pair("height", int_type.CreateValue(480, nullptr)));
+  object.insert(std::make_pair(
+      "width", int_type.CreateValue(base::FundamentalValue{640}, nullptr)));
+  object.insert(std::make_pair(
+      "height", int_type.CreateValue(base::FundamentalValue{480}, nullptr)));
   EXPECT_JSON_EQ("{'height':480,'width':640}", *TypedValueToJson(object));
 }
 
@@ -63,8 +63,8 @@
   IntPropType int_type;
   ValueVector arr;
 
-  arr.push_back(int_type.CreateValue(640, nullptr));
-  arr.push_back(int_type.CreateValue(480, nullptr));
+  arr.push_back(int_type.CreateValue(base::FundamentalValue{640}, nullptr));
+  arr.push_back(int_type.CreateValue(base::FundamentalValue{480}, nullptr));
   EXPECT_JSON_EQ("[640,480]", *TypedValueToJson(arr));
 }
 
@@ -175,9 +175,10 @@
   EXPECT_TRUE(TypedValueFromJson(CreateValue("{'age':20,'name':'Bob'}").get(),
                                  &type, &value, nullptr));
   ValueMap value2;
-  value2.insert(std::make_pair("age", age_prop.CreateValue(20, nullptr)));
   value2.insert(std::make_pair(
-      "name", name_prop.CreateValue(std::string("Bob"), nullptr)));
+      "age", age_prop.CreateValue(base::FundamentalValue{20}, nullptr)));
+  value2.insert(std::make_pair(
+      "name", name_prop.CreateValue(base::StringValue("Bob"), nullptr)));
   EXPECT_EQ(value2, value);
 
   chromeos::ErrorPtr error;
@@ -197,8 +198,8 @@
   EXPECT_TRUE(TypedValueFromJson(CreateValue("['foo', 'bar']").get(), &type,
                                  &arr, nullptr));
   ValueVector arr2;
-  arr2.push_back(str_type.CreateValue(std::string{"foo"}, nullptr));
-  arr2.push_back(str_type.CreateValue(std::string{"bar"}, nullptr));
+  arr2.push_back(str_type.CreateValue(base::StringValue{"foo"}, nullptr));
+  arr2.push_back(str_type.CreateValue(base::StringValue{"bar"}, nullptr));
   EXPECT_EQ(arr2, arr);
 
   chromeos::ErrorPtr error;
diff --git a/libweave/src/privet/cloud_delegate.cc b/libweave/src/privet/cloud_delegate.cc
index 80bb052..df8647c 100644
--- a/libweave/src/privet/cloud_delegate.cc
+++ b/libweave/src/privet/cloud_delegate.cc
@@ -13,7 +13,6 @@
 #include <base/message_loop/message_loop.h>
 #include <base/values.h>
 #include <chromeos/errors/error.h>
-#include <chromeos/variant_dictionary.h>
 
 #include "libweave/src/buffet_config.h"
 #include "libweave/src/commands/command_manager.h"
@@ -22,7 +21,6 @@
 #include "libweave/src/states/state_manager.h"
 
 using chromeos::ErrorPtr;
-using chromeos::VariantDictionary;
 
 namespace weave {
 namespace privet {
diff --git a/libweave/src/states/state_change_queue_interface.h b/libweave/src/states/state_change_queue_interface.h
index f92c690..5adae58 100644
--- a/libweave/src/states/state_change_queue_interface.h
+++ b/libweave/src/states/state_change_queue_interface.h
@@ -9,7 +9,6 @@
 
 #include <base/callback_list.h>
 #include <base/time/time.h>
-#include <chromeos/variant_dictionary.h>
 
 #include "libweave/src/commands/schema_utils.h"
 
diff --git a/libweave/src/states/state_package_unittest.cc b/libweave/src/states/state_package_unittest.cc
index 8900e7f..0bd4be8 100644
--- a/libweave/src/states/state_package_unittest.cc
+++ b/libweave/src/states/state_package_unittest.cc
@@ -299,8 +299,8 @@
 TEST_F(StatePackageTest, SetPropertyValue_Error_Object_TypeMismatch) {
   chromeos::ErrorPtr error;
   ASSERT_FALSE(package_->SetPropertyValue(
-      "direction", *CreateDictionaryValue("{'altitude': 45.0, 'azimuth': '15'}"),
-      &error));
+      "direction",
+      *CreateDictionaryValue("{'altitude': 45.0, 'azimuth': '15'}"), &error));
   EXPECT_EQ(errors::commands::kDomain, error->GetDomain());
   EXPECT_EQ(errors::commands::kInvalidPropValue, error->GetCode());
   const chromeos::Error* inner = error->GetInnerError();