buffet: Use DBus utilities in buffet_client

Use chromeos::dbus_utils::AppendValueToWriter to send a dictionary
over DBus instead of writing it out manually.

Also added a parameter to TestMethod for more testing of DBus
communication between Buffet and buffet_client. Buffet replies
with the same string parameters (like an 'echo' service).

BUG=chromium:374864
TEST=USE=buffet P2_TEST_FILTER="buffet::*" FEATURES=test emerge-link platform2

Change-Id: Ib9d5a8e5173fac894e742cfda5f3fb52ea96f15b
Reviewed-on: https://chromium-review.googlesource.com/212683
Reviewed-by: Christopher Wiley <wiley@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 1b61a83..ce8a928 100644
--- a/buffet/buffet_client.cc
+++ b/buffet/buffet_client.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <iostream>  // NOLINT(readability/streams)
+#include <memory>
 #include <string>
 #include <sysexits.h>
 
@@ -11,6 +12,7 @@
 #include <base/memory/ref_counted.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/values.h>
+#include <chromeos/dbus_utils.h>
 #include <dbus/bus.h>
 #include <dbus/message.h>
 #include <dbus/object_proxy.h>
@@ -27,7 +29,7 @@
 
 void usage() {
   std::cerr << "Possible commands:" << std::endl;
-  std::cerr << "  " << kManagerTestMethod << std::endl;
+  std::cerr << "  " << kManagerTestMethod << " <message>" << std::endl;
   std::cerr << "  " << kManagerCheckDeviceRegistered << std::endl;
   std::cerr << "  " << kManagerGetDeviceInfo << std::endl;
   std::cerr << "  " << kManagerStartRegisterDevice
@@ -54,14 +56,26 @@
   }
 
   int CallTestMethod(const CommandLine::StringVector& args) {
+    std::string message;
+    if (!args.empty())
+      message = args.front();
+
     dbus::MethodCall method_call(kManagerInterface, kManagerTestMethod);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(message);
     scoped_ptr<dbus::Response> response(
         manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
     if (!response) {
       std::cout << "Failed to receive a response." << std::endl;
       return EX_UNAVAILABLE;
     }
-    std::cout << "Received a response." << std::endl;
+    dbus::MessageReader reader(response.get());
+    std::string response_message;
+    if (!reader.PopString(&response_message)) {
+      std::cout << "No valid response." << std::endl;
+      return EX_SOFTWARE;
+    }
+    std::cout << "Received a response: " << response_message << std::endl;
     return EX_OK;
   }
 
@@ -132,31 +146,21 @@
       usage();
       return EX_USAGE;
     }
-    std::map<std::string, std::shared_ptr<base::Value>> params;
+    chromeos::dbus_utils::Dictionary params;
 
     if (!args.empty()) {
       auto key_values = buffet::data_encoding::WebParamsDecode(args.front());
       for (const auto& pair : key_values) {
         params.insert(std::make_pair(
-          pair.first, std::shared_ptr<base::Value>(
-              base::Value::CreateStringValue(pair.second))));
+            pair.first, std::unique_ptr<base::Value>(
+                base::Value::CreateStringValue(pair.second))));
       }
     }
 
     dbus::MethodCall method_call(
         kManagerInterface, kManagerStartRegisterDevice);
     dbus::MessageWriter writer(&method_call);
-    dbus::MessageWriter dict_writer(nullptr);
-    writer.OpenArray("{sv}", &dict_writer);
-    for (const auto& pair : params) {
-      dbus::MessageWriter dict_entry_writer(nullptr);
-      dict_writer.OpenDictEntry(&dict_entry_writer);
-      dict_entry_writer.AppendString(pair.first);
-      dbus::AppendBasicTypeValueDataAsVariant(&dict_entry_writer,
-                                              *pair.second.get());
-      dict_writer.CloseContainer(&dict_entry_writer);
-    }
-    writer.CloseContainer(&dict_writer);
+    chromeos::dbus_utils::AppendValueToWriter(&writer, params);
 
     static const int timeout_ms = 3000;
     scoped_ptr<dbus::Response> response(
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 749e84a..9a11040 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -119,8 +119,10 @@
   state_.SetValue(json_state_fragment);
 }
 
-void Manager::HandleTestMethod(chromeos::ErrorPtr* error) {
-  LOG(INFO) << "Received call to test method";
+std::string Manager::HandleTestMethod(chromeos::ErrorPtr* error,
+                                      const std::string& message) {
+  LOG(INFO) << "Received call to test method: " << message;
+  return message;
 }
 
 }  // namespace buffet
diff --git a/buffet/manager.h b/buffet/manager.h
index 73ed8aa..ba7190d 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -59,7 +59,8 @@
   void HandleUpdateState(chromeos::ErrorPtr* error,
                          const std::string& json_state_fragment);
   // Handles calls to org.chromium.Buffet.Manager.Test()
-  void HandleTestMethod(chromeos::ErrorPtr* error);
+  std::string HandleTestMethod(chromeos::ErrorPtr* error,
+                               const std::string& message);
 
   chromeos::dbus_utils::DBusObject dbus_object_;