libbrillo: add support for "a(ubay)" D-Bus type

The "a(ubay)" D-Bus type is needed by shill to handle the Pco property
of the org.freedesktop.ModemManager1.Modem3gpp interface exposed by
ModemManager.

BUG=b:112664666
TEST=Run unit tests.

Change-Id: Ia4ca839c6c8b77ed552f379f9144dd4c8bfc2d11
Reviewed-on: https://chromium-review.googlesource.com/1181529
Commit-Ready: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Dan Erat <derat@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/brillo/dbus/data_serialization.cc b/brillo/dbus/data_serialization.cc
index 4cae471..5776b8c 100644
--- a/brillo/dbus/data_serialization.cc
+++ b/brillo/dbus/data_serialization.cc
@@ -232,6 +232,9 @@
   else if (signature == "a(uu)")
     return PopTypedArrayFromReader<
         std::tuple<uint32_t, uint32_t>>(reader, value);
+  else if (signature == "a(ubay)")
+    return PopTypedArrayFromReader<
+        std::tuple<uint32_t, bool, std::vector<uint8_t>>>(reader, value);
 
   // When a use case for particular array signature is found, feel free
   // to add handing for it here.
diff --git a/brillo/dbus/data_serialization_unittest.cc b/brillo/dbus/data_serialization_unittest.cc
index 1b6975d..1257e49 100644
--- a/brillo/dbus/data_serialization_unittest.cc
+++ b/brillo/dbus/data_serialization_unittest.cc
@@ -472,19 +472,28 @@
   std::vector<double> dbl_array_empty{};
   std::map<std::string, std::string> dict_ss{{"k1", "v1"}, {"k2", "v2"}};
   VariantDictionary dict_sv{{"k1", 1}, {"k2", "v2"}};
+  using ComplexStructArray =
+      std::vector<std::tuple<uint32_t, bool, std::vector<uint8_t>>>;
+  ComplexStructArray complex_struct_array{
+      {123, true, {0xaa, 0xbb, 0xcc}},
+      {456, false, {0xdd}},
+      {789, false, {}},
+  };
   AppendValueToWriterAsVariant(&writer, int_array);
   AppendValueToWriterAsVariant(&writer, str_array);
   AppendValueToWriterAsVariant(&writer, dbl_array_empty);
   AppendValueToWriterAsVariant(&writer, dict_ss);
   AppendValueToWriterAsVariant(&writer, dict_sv);
+  AppendValueToWriterAsVariant(&writer, complex_struct_array);
 
-  EXPECT_EQ("vvvvv", message->GetSignature());
+  EXPECT_EQ("vvvvvv", message->GetSignature());
 
   Any int_array_out;
   Any str_array_out;
   Any dbl_array_out;
   Any dict_ss_out;
   Any dict_sv_out;
+  Any complex_struct_array_out;
 
   MessageReader reader(message.get());
   EXPECT_TRUE(PopValueFromReader(&reader, &int_array_out));
@@ -492,6 +501,7 @@
   EXPECT_TRUE(PopValueFromReader(&reader, &dbl_array_out));
   EXPECT_TRUE(PopValueFromReader(&reader, &dict_ss_out));
   EXPECT_TRUE(PopValueFromReader(&reader, &dict_sv_out));
+  EXPECT_TRUE(PopValueFromReader(&reader, &complex_struct_array_out));
   EXPECT_FALSE(reader.HasMoreData());
 
   EXPECT_EQ(int_array, int_array_out.Get<std::vector<int>>());
@@ -502,6 +512,8 @@
             dict_sv_out.Get<VariantDictionary>().at("k1").Get<int>());
   EXPECT_EQ(dict_sv["k2"].Get<const char*>(),
             dict_sv_out.Get<VariantDictionary>().at("k2").Get<std::string>());
+  EXPECT_EQ(complex_struct_array,
+            complex_struct_array_out.Get<ComplexStructArray>());
 }
 
 TEST(DBusUtils, VariantDictionary) {