libchromeos: Add generic DBus data serialization/deserialization

Provide generic methods to write arbitrary C++ data to D-Bus
message buffers and read it back. Implement generic conatainer
support such as std::vector, std::map, std::pair to support
D-Bus ARRAY, DICT, STRUCT data types. Also using chromeos::Any
as a D-Bus VARIANT type.

Added a bunch of unit tests for dbus_utils.

BUG=None
TEST=FEATURES=test emerge-link libchromeos
     FEATURES=test emerge-link buffet

Change-Id: Ic445e11fb2e65c8243df183c6e93c4b3cb881dc8
Reviewed-on: https://chromium-review.googlesource.com/213923
Reviewed-by: Ben Chan <benchan@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/buffet_client.cc b/buffet/buffet_client.cc
index 7c0c454..c42e484 100644
--- a/buffet/buffet_client.cc
+++ b/buffet/buffet_client.cc
@@ -12,6 +12,7 @@
 #include <base/memory/ref_counted.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/values.h>
+#include <chromeos/any.h>
 #include <chromeos/data_encoding.h>
 #include <chromeos/dbus_utils.h>
 #include <dbus/bus.h>
@@ -151,16 +152,15 @@
     if (!args.empty()) {
       auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
       for (const auto& pair : key_values) {
-        params.insert(std::make_pair(
-            pair.first, std::unique_ptr<base::Value>(
-                base::Value::CreateStringValue(pair.second))));
+        params.insert(std::make_pair(pair.first, chromeos::Any(pair.second)));
       }
     }
 
     dbus::MethodCall method_call(
         kManagerInterface, kManagerStartRegisterDevice);
     dbus::MessageWriter writer(&method_call);
-    chromeos::dbus_utils::AppendValueToWriter(&writer, params);
+    CHECK(chromeos::dbus_utils::AppendValueToWriter(&writer, params))
+        << "Failed to send the parameters over D-Bus";
 
     static const int timeout_ms = 3000;
     scoped_ptr<dbus::Response> response(
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 3e09f30..a1cb374 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -53,14 +53,15 @@
     FILE_PATH_LITERAL("/var/lib/buffet/device_reg_info");
 
 bool GetParamValue(
-    const std::map<std::string, std::unique_ptr<base::Value>>& params,
+    const std::map<std::string, std::string>& params,
     const std::string& param_name,
     std::string* param_value) {
   auto p = params.find(param_name);
   if (p == params.end())
     return false;
 
-  return p->second->GetAsString(param_value);
+  *param_value = p->second;
+  return true;
 }
 
 std::pair<std::string, std::string> BuildAuthHeader(
@@ -335,7 +336,7 @@
 }
 
 std::string DeviceRegistrationInfo::StartRegistration(
-    const std::map<std::string, std::unique_ptr<base::Value>>& params,
+    const std::map<std::string, std::string>& params,
     chromeos::ErrorPtr* error) {
   GetParamValue(params, storage_keys::kClientId, &client_id_);
   GetParamValue(params, storage_keys::kClientSecret, &client_secret_);
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index cdba4aa..1f7d1fb 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -95,8 +95,9 @@
   // key-value pairs of device information, such as client_id, client_secret,
   // and so on. If a particular key-value pair is omitted, a default value
   // is used when possible. Returns a device claim ID on success.
+  // The values are all strings for now.
   std::string StartRegistration(
-    const std::map<std::string, std::unique_ptr<base::Value>>& params,
+    const std::map<std::string, std::string>& params,
     chromeos::ErrorPtr* error);
 
   // Finalizes the device registration. If |user_auth_code| is provided, then
diff --git a/buffet/device_registration_info_unittest.cc b/buffet/device_registration_info_unittest.cc
index 268e56e..779e29e 100644
--- a/buffet/device_registration_info_unittest.cc
+++ b/buffet/device_registration_info_unittest.cc
@@ -325,7 +325,7 @@
   transport_->AddHandler(dev_reg_->GetServiceURL("registrationTickets"),
                          request_type::kPost,
                          base::Bind(create_ticket));
-  std::map<std::string, std::unique_ptr<base::Value>> params;
+  std::map<std::string, std::string> params;
   std::string json_resp = dev_reg_->StartRegistration(params, nullptr);
   auto json = std::unique_ptr<base::Value>(base::JSONReader::Read(json_resp));
   EXPECT_NE(nullptr, json.get());
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 9a11040..ee7379f 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -97,8 +97,7 @@
 
 std::string Manager::HandleStartRegisterDevice(
     chromeos::ErrorPtr* error,
-    const std::map<std::string,
-    std::unique_ptr<base::Value>>& params) {
+    const std::map<std::string, std::string>& params) {
   LOG(INFO) << "Received call to Manager.StartRegisterDevice()";
 
   return device_info_->StartRegistration(params, error);
diff --git a/buffet/manager.h b/buffet/manager.h
index ba7190d..2a7995c 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -51,7 +51,7 @@
   // Handles calls to org.chromium.Buffet.Manager.StartRegisterDevice().
   std::string HandleStartRegisterDevice(chromeos::ErrorPtr* error,
                                         const std::map<std::string,
-                                        std::unique_ptr<base::Value>>& params);
+                                                       std::string>& params);
   // Handles calls to org.chromium.Buffet.Manager.FinishRegisterDevice().
   std::string HandleFinishRegisterDevice(chromeos::ErrorPtr* error,
                                          const std::string& user_auth_code);