hidl2aidl: add support for array and vector translation am: 8cc4e9a907
Original change: https://android-review.googlesource.com/c/platform/system/tools/hidl/+/1511709
Change-Id: I1aabd885dd8fb3718cdc9b4b66dd6fccf4a0e73a
diff --git a/hidl2aidl/AidlTranslate.cpp b/hidl2aidl/AidlTranslate.cpp
index 345fb19..1840bae 100644
--- a/hidl2aidl/AidlTranslate.cpp
+++ b/hidl2aidl/AidlTranslate.cpp
@@ -25,11 +25,15 @@
#include <vector>
#include "AidlHelper.h"
+#include "ArrayType.h"
#include "CompoundType.h"
+#include "ConstantExpression.h"
#include "Coordinator.h"
+#include "EnumType.h"
#include "NamedType.h"
#include "ScalarType.h"
#include "Scope.h"
+#include "VectorType.h"
namespace android {
@@ -59,12 +63,12 @@
}
}
-static const std::string aidlTypePackage(const NamedType* type, AidlBackend backend) {
+static const std::string aidlTypePackage(const NamedType& type, AidlBackend backend) {
const std::string prefix = (backend == AidlBackend::NDK) ? "aidl::" : std::string();
const std::string separator = (backend == AidlBackend::JAVA) ? "." : "::";
return prefix +
- base::Join(base::Split(AidlHelper::getAidlPackage(type->fqName()), "."), separator) +
- separator + AidlHelper::getAidlType(*type, type->fqName());
+ base::Join(base::Split(AidlHelper::getAidlPackage(type.fqName()), "."), separator) +
+ separator + AidlHelper::getAidlType(type, type.fqName());
}
static void namedTypeTranslation(Formatter& out, const std::set<const NamedType*>& namedTypes,
@@ -100,10 +104,10 @@
<< "(h2aTranslate(in." << field.fullName << "()));\n";
} else {
out << "{\n";
- out << aidlTypePackage(type, backend) << " " << field.field->name() << ";\n";
+ out << aidlTypePackage(*type, backend) << " " << field.field->name() << ";\n";
out << "if (!translate(in." << field.fullName + "(), &" << field.field->name()
<< ")) return false;\n";
- out << "out->set<" << aidlTypePackage(parent, backend) << "::" << field.fullName
+ out << "out->set<" << aidlTypePackage(*parent, backend) << "::" << field.fullName
<< ">(" << field.field->name() << ");\n";
out << "}\n";
}
@@ -111,34 +115,32 @@
}
}
-static void h2aScalarChecks(Formatter& out, const FieldWithVersion& field,
- const CompoundType* parent, AidlBackend backend) {
+static void h2aScalarChecks(Formatter& out, const Type& type, const std::string& inputAccess,
+ AidlBackend backend) {
static const std::map<ScalarType::Kind, size_t> kSignedMaxSize{
{ScalarType::KIND_UINT8, std::numeric_limits<int8_t>::max()},
{ScalarType::KIND_INT16, std::numeric_limits<int32_t>::max()},
{ScalarType::KIND_UINT32, std::numeric_limits<int32_t>::max()},
{ScalarType::KIND_UINT64, std::numeric_limits<int64_t>::max()}};
-
- const ScalarType* scalarType = field.field->type().resolveToScalarType();
- if (scalarType != nullptr) {
+ const ScalarType* scalarType = type.resolveToScalarType();
+ if (scalarType != nullptr && !type.isEnum()) {
const auto& it = kSignedMaxSize.find(scalarType->getKind());
if (it != kSignedMaxSize.end()) {
out << "// FIXME This requires conversion between signed and unsigned. Change this if "
"it doesn't suit your needs.\n";
- std::string functionCall = (parent->style() == CompoundType::STYLE_STRUCT) ? "" : "()";
if (scalarType->getKind() == ScalarType::KIND_INT16) {
// AIDL uses an unsigned 16-bit integer(char16_t), so this is signed to unsigned.
- out << "if (in." << field.fullName << functionCall << " < 0) {\n";
+ out << "if (" << inputAccess << " < 0) {\n";
} else {
std::string affix = (scalarType->getKind() == ScalarType::KIND_UINT64) ? "L" : "";
- out << "if (in." << field.fullName << functionCall << " > " << it->second << affix
- << " || in." << field.fullName << functionCall << " < 0) {\n";
+ out << "if (" << inputAccess << " > " << it->second << affix << " || "
+ << inputAccess << " < 0) {\n";
}
if (backend == AidlBackend::JAVA) {
out.indent([&] {
out << "throw new RuntimeException(\"Unsafe conversion between signed and "
"unsigned scalars for field: "
- << field.fullName << "\");\n";
+ << inputAccess << "\");\n";
});
} else {
out.indent([&] { out << "return false;\n"; });
@@ -157,10 +159,15 @@
}
static std::string wrapStaticCast(const std::string& payload, const Type& type,
- const FQName& fqName) {
+ const FQName& fqName, AidlBackend backend) {
static const std::map<std::string, std::string> kAidlBackendScalarTypes{
{"boolean", "bool"}, {"byte", "int8_t"}, {"char", "char16_t"}, {"int", "int32_t"},
{"long", "int64_t"}, {"float", "float"}, {"double", "double"}};
+ if (type.isEnum()) {
+ return "static_cast<" +
+ aidlTypePackage(static_cast<const android::NamedType&>(type), backend) + ">(" +
+ payload + ")";
+ }
const auto& it = kAidlBackendScalarTypes.find(AidlHelper::getAidlType(type, fqName));
if (it != kAidlBackendScalarTypes.end()) {
return "static_cast<" + it->second + ">(" + payload + ")";
@@ -174,30 +181,100 @@
if (type.isString()) {
return wrapToString16(payload, backend);
} else {
- return wrapStaticCast(payload, type, fqName);
+ return wrapStaticCast(payload, type, fqName, backend);
+ }
+}
+
+static void containerTranslation(Formatter& out, const FieldWithVersion& field,
+ const CompoundType* parent, AidlBackend backend) {
+ const Type* elementType;
+ std::string javaSizeAccess;
+ std::string javaElementAccess;
+ std::string cppSize;
+ if (field.field->type().isArray()) {
+ elementType = static_cast<const ArrayType*>(field.field->get())->getElementType();
+ javaSizeAccess = ".length";
+ javaElementAccess = "[i]";
+ cppSize = "sizeof(in." + field.fullName + ")/sizeof(in." + field.fullName + "[0])";
+ } else if (field.field->type().isVector()) {
+ elementType = static_cast<const VectorType*>(field.field->get())->getElementType();
+ javaSizeAccess = ".size()";
+ javaElementAccess = ".get(i)";
+ cppSize = "in." + field.fullName + ".size()";
+ } else {
+ LOG(FATAL) << "Unexpected container type for field: " << field.field->name();
+ return;
+ }
+ if (elementType->isArray() || elementType->isVector()) {
+ out << "#error Nested arrays and vectors are currently not supported. Needs implementation "
+ "for field: "
+ << field.field->name() << "\n";
+ return;
+ }
+ if (elementType->isNamedType() && !elementType->isEnum()) {
+ out << "#error Arrays of NamedTypes are not currently not supported. Needs implementation "
+ "for field: "
+ << field.field->name() << "\n";
+ return;
+ }
+ if (backend == AidlBackend::JAVA) {
+ const std::string inputAccess = "in." + field.fullName;
+ out << "if (" << inputAccess << " != null) {\n";
+ out.indent([&] {
+ out << "out." << field.field->name() << " = new " << elementType->getJavaType(true)
+ << "[" << inputAccess << javaSizeAccess << "];\n";
+ out << "for (int i = 0; i < " << inputAccess << javaSizeAccess << "; i++) {\n";
+ out.indent([&] {
+ h2aScalarChecks(out, *elementType, inputAccess + javaElementAccess, backend);
+ out << "out." << field.field->name() << "[i] = " << inputAccess << javaElementAccess
+ << ";\n";
+ });
+ out << "}\n";
+ });
+ out << "}\n";
+ } else {
+ const std::string inputAccessElement = "in." + field.fullName + "[i]";
+ out << "{\n";
+ out.indent([&] {
+ out << "size_t size = " << cppSize << ";\n";
+ out << "for (size_t i = 0; i < size; i++) {\n";
+ out.indent([&] {
+ h2aScalarChecks(out, *elementType, inputAccessElement, backend);
+ out << "out->" << field.field->name() << ".push_back("
+ << wrapCppSource(inputAccessElement, *elementType, parent->fqName(), backend)
+ << ");\n";
+ });
+ out << "}\n";
+ });
+ out << "}\n";
}
}
static void simpleTranslation(Formatter& out, const FieldWithVersion& field,
const CompoundType* parent, AidlBackend backend) {
- h2aScalarChecks(out, field, parent, backend);
+ std::string inputAccess = "in." + field.fullName;
if (backend == AidlBackend::JAVA) {
if (parent->style() == CompoundType::STYLE_STRUCT) {
- out << "out." << field.field->name() << " = in." << field.fullName << ";\n";
+ h2aScalarChecks(out, field.field->type(), inputAccess, backend);
+ out << "out." << field.field->name() << " = " << inputAccess << ";\n";
} else {
- out << "out.set" << StringHelper::Capitalize(field.fullName) << "(in."
- << field.field->name() << "());\n";
+ inputAccess += "()";
+ h2aScalarChecks(out, field.field->type(), inputAccess, backend);
+ out << "out.set" << StringHelper::Capitalize(field.fullName) << "(" << inputAccess
+ << ");\n";
}
} else {
if (parent->style() == CompoundType::STYLE_STRUCT) {
+ h2aScalarChecks(out, field.field->type(), inputAccess, backend);
out << "out->" << field.field->name() << " = "
- << wrapCppSource("in." + field.fullName, *field.field->get(), parent->fqName(),
+ << wrapCppSource("in." + field.fullName, field.field->type(), parent->fqName(),
backend)
<< ";\n";
} else {
+ inputAccess += "()";
+ h2aScalarChecks(out, field.field->type(), inputAccess, backend);
out << "*out = "
- << wrapCppSource("in." + field.fullName + "()", *field.field->get(),
- parent->fqName(), backend)
+ << wrapCppSource(inputAccess, field.field->type(), parent->fqName(), backend)
<< ";\n";
}
}
@@ -209,6 +286,8 @@
// TODO(b/158489355) Need to support and validate more types like arrays/vectors.
if (field.field->type().isNamedType()) {
namedTypeTranslation(out, namedTypes, field, parent, backend);
+ } else if (field.field->type().isArray() || field.field->type().isVector()) {
+ containerTranslation(out, field, parent, backend);
} else if (field.field->type().isEnum() || field.field->type().isScalar() ||
field.field->type().isString()) {
simpleTranslation(out, field, parent, backend);
@@ -221,11 +300,11 @@
static const std::string declareAidlFunctionSignature(const NamedType* type, AidlBackend backend) {
if (backend == AidlBackend::JAVA) {
- return "static public " + aidlTypePackage(type, backend) + " h2aTranslate(" +
+ return "static public " + aidlTypePackage(*type, backend) + " h2aTranslate(" +
type->fullJavaName() + " in)";
} else {
return "__attribute__((warn_unused_result)) bool translate(const " + type->fullName() +
- "& in, " + aidlTypePackage(type, backend) + "* out)";
+ "& in, " + aidlTypePackage(*type, backend) + "* out)";
}
}
@@ -332,8 +411,8 @@
if (compound->style() == CompoundType::STYLE_SAFE_UNION) {
out.indent([&] {
if (backend == AidlBackend::JAVA) {
- out << aidlTypePackage(type, backend) << " out = new "
- << aidlTypePackage(type, backend) << "();\n";
+ out << aidlTypePackage(*type, backend) << " out = new "
+ << aidlTypePackage(*type, backend) << "();\n";
}
out << "switch (in.getDiscriminator()) {\n";
out.indent([&] {
@@ -366,8 +445,8 @@
} else {
out.indent([&] {
if (backend == AidlBackend::JAVA) {
- out << aidlTypePackage(type, backend) << " out = new "
- << aidlTypePackage(type, backend) << "();\n";
+ out << aidlTypePackage(*type, backend) << " out = new "
+ << aidlTypePackage(*type, backend) << "();\n";
}
const ProcessedCompoundType& processedType = it->second;
for (const auto& field : processedType.fields) {
diff --git a/hidl2aidl/test/1.2/types.hal b/hidl2aidl/test/1.2/types.hal
index 0371a8e..12990b9 100644
--- a/hidl2aidl/test/1.2/types.hal
+++ b/hidl2aidl/test/1.2/types.hal
@@ -18,6 +18,7 @@
import @1.1::OnlyIn11;
import @1.1::NameCollision;
+import @1.1::Value;
import android.hidl.safe_union@1.0::Monostate;
struct NameCollision {
@@ -45,3 +46,18 @@
float e;
double f;
};
+
+struct ArrayFoo {
+ int8_t[12] a;
+ uint32_t[12] b;
+ @1.1::Value[12] c;
+ string[2] d;
+};
+
+struct VectorFoo {
+ vec<int8_t> a;
+ vec<uint32_t> b;
+ vec<@1.1::Value> c;
+ vec<string> d;
+};
+
diff --git a/hidl2aidl/test/Android.bp b/hidl2aidl/test/Android.bp
index 28e2558..696b7d3 100644
--- a/hidl2aidl/test/Android.bp
+++ b/hidl2aidl/test/Android.bp
@@ -40,6 +40,8 @@
name: "hidl2aidl_test_gen_aidl",
defaults: ["hidl2aidl_test_gen_defaults"],
out: [
+ "hidl2aidl/test/ArrayFoo.aidl",
+ "hidl2aidl/test/VectorFoo.aidl",
"hidl2aidl/test/IBar.aidl",
"hidl2aidl/test/IBarInner.aidl",
"hidl2aidl/test/IFoo.aidl",
diff --git a/hidl2aidl/test/TranslateJavaTest.java b/hidl2aidl/test/TranslateJavaTest.java
index 6e9cbcd..5ff8550 100644
--- a/hidl2aidl/test/TranslateJavaTest.java
+++ b/hidl2aidl/test/TranslateJavaTest.java
@@ -115,7 +115,7 @@
fail("Expected an exception to be thrown for out of bounds unsigned to signed translation");
} catch (RuntimeException e) {
String message = e.getMessage();
- assertThat("Unsafe conversion between signed and unsigned scalars for field: a",
+ assertThat("Unsafe conversion between signed and unsigned scalars for field: in.a",
is(message));
}
}
@@ -191,4 +191,102 @@
dest = Translate.h2aTranslate(source);
assertThat(source.f(), is(dest.getF()));
}
+
+ @Test
+ public void ArrayFoo() {
+ hidl2aidl.test.ArrayFoo dest;
+ hidl2aidl.test.V1_2.ArrayFoo source = new hidl2aidl.test.V1_2.ArrayFoo();
+ source.a[0] = 42;
+ source.a[0] = 42;
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.a[0], is(dest.a[0]));
+ }
+
+ @Test
+ public void ArrayFooEmpty() {
+ hidl2aidl.test.ArrayFoo dest;
+ hidl2aidl.test.V1_2.ArrayFoo source = new hidl2aidl.test.V1_2.ArrayFoo();
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.a.length, is(dest.a.length));
+ }
+
+ @Test
+ public void ArrayFooEnum() {
+ hidl2aidl.test.ArrayFoo dest;
+ hidl2aidl.test.V1_2.ArrayFoo source = new hidl2aidl.test.V1_2.ArrayFoo();
+ source.c[0] = hidl2aidl.test.Value.A;
+ source.c[1] = hidl2aidl.test.Value.B;
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.c[0], is(dest.c[0]));
+ assertThat(source.c[1], is(dest.c[1]));
+ }
+
+ @Test
+ public void ArrayFooString() {
+ hidl2aidl.test.ArrayFoo dest;
+ hidl2aidl.test.V1_2.ArrayFoo source = new hidl2aidl.test.V1_2.ArrayFoo();
+ source.d[0] = "hello";
+ source.d[1] = "world";
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.d[0], is(dest.d[0]));
+ assertThat(source.d[1], is(dest.d[1]));
+ }
+
+ @Test
+ public void VectorFoo() {
+ hidl2aidl.test.VectorFoo dest;
+ hidl2aidl.test.V1_2.VectorFoo source = new hidl2aidl.test.V1_2.VectorFoo();
+ source.a.add((byte) 42);
+ source.a.add((byte) 8);
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.a.get(0), is(dest.a[0]));
+ assertThat(source.a.get(1), is(dest.a[1]));
+ }
+
+ @Test
+ public void VectorFooEmpty() {
+ hidl2aidl.test.VectorFoo dest;
+ hidl2aidl.test.V1_2.VectorFoo source = new hidl2aidl.test.V1_2.VectorFoo();
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.a.size(), is(dest.a.length));
+ }
+
+ @Test
+ public void VectorFooUnsigned() {
+ hidl2aidl.test.VectorFoo dest;
+ hidl2aidl.test.V1_2.VectorFoo source = new hidl2aidl.test.V1_2.VectorFoo();
+ source.b.add(12);
+ source.b.add(0xf0000000);
+ try {
+ dest = Translate.h2aTranslate(source);
+ fail("Expected an exception to be thrown for out of bounds unsigned to signed translation");
+ } catch (RuntimeException e) {
+ String message = e.getMessage();
+ assertThat(
+ "Unsafe conversion between signed and unsigned scalars for field: in.b.get(i)",
+ is(message));
+ }
+ }
+
+ @Test
+ public void VectorFooEnum() {
+ hidl2aidl.test.VectorFoo dest;
+ hidl2aidl.test.V1_2.VectorFoo source = new hidl2aidl.test.V1_2.VectorFoo();
+ source.c.add(hidl2aidl.test.Value.A);
+ source.c.add(hidl2aidl.test.Value.B);
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.c.get(0), is(dest.c[0]));
+ assertThat(source.c.get(1), is(dest.c[1]));
+ }
+
+ @Test
+ public void VectorFooString() {
+ hidl2aidl.test.VectorFoo dest;
+ hidl2aidl.test.V1_2.VectorFoo source = new hidl2aidl.test.V1_2.VectorFoo();
+ source.d.add("hello");
+ source.d.add("world");
+ dest = Translate.h2aTranslate(source);
+ assertThat(source.d.get(0), is(dest.d[0]));
+ assertThat(source.d.get(1), is(dest.d[1]));
+ }
}
diff --git a/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/ArrayFoo.aidl b/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/ArrayFoo.aidl
new file mode 100644
index 0000000..0354af6
--- /dev/null
+++ b/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/ArrayFoo.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package hidl2aidl.test;
+@VintfStability
+parcelable ArrayFoo {
+ byte[] a;
+ int[] b;
+ hidl2aidl.test.Value[] c;
+ String[] d;
+}
diff --git a/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/VectorFoo.aidl b/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/VectorFoo.aidl
new file mode 100644
index 0000000..d2e8b76
--- /dev/null
+++ b/hidl2aidl/test/aidl_api/hidl2aidl_test_gen/current/hidl2aidl/test/VectorFoo.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package hidl2aidl.test;
+@VintfStability
+parcelable VectorFoo {
+ byte[] a;
+ int[] b;
+ hidl2aidl.test.Value[] c;
+ String[] d;
+}
diff --git a/hidl2aidl/test/translate_cpp_test.cpp b/hidl2aidl/test/translate_cpp_test.cpp
index 0b2bf1c..0d94c29 100644
--- a/hidl2aidl/test/translate_cpp_test.cpp
+++ b/hidl2aidl/test/translate_cpp_test.cpp
@@ -23,134 +23,110 @@
namespace android {
TEST_F(Hidl2aidlTranslateTest, OnlyIn10) {
- bool ret;
hidl2aidl::test::OnlyIn10 dest;
hidl2aidl::test::V1_0::OnlyIn10 source;
source.str = "Hello";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.str, String8(dest.str).c_str());
}
TEST_F(Hidl2aidlTranslateTest, OnlyIn11) {
- bool ret;
hidl2aidl::test::OnlyIn11 dest;
hidl2aidl::test::V1_1::OnlyIn11 source;
source.str = 12;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.str, dest.str);
}
TEST_F(Hidl2aidlTranslateTest, OverrideMe) {
- bool ret;
hidl2aidl::test::OverrideMe dest;
hidl2aidl::test::V1_1::OverrideMe source;
source.a = "World";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, String8(dest.a).c_str());
}
TEST_F(Hidl2aidlTranslateTest, Outer) {
- bool ret;
hidl2aidl::test::Outer dest;
hidl2aidl::test::V1_1::Outer source;
source.a = 12;
source.v1_0.inner.a = 16;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, dest.a);
EXPECT_EQ(source.v1_0.inner.a, dest.inner.a);
}
TEST_F(Hidl2aidlTranslateTest, OuterInner) {
- bool ret;
hidl2aidl::test::OuterInner dest;
hidl2aidl::test::V1_0::Outer::Inner source;
source.a = 12;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, dest.a);
}
TEST_F(Hidl2aidlTranslateTest, NameCollision) {
- bool ret;
hidl2aidl::test::NameCollision dest;
hidl2aidl::test::V1_2::NameCollision source;
source.reference.reference.a = 12;
source.reference.b = "Fancy";
source.c = "Car";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.reference.reference.a, dest.a);
EXPECT_EQ(source.reference.b, String8(dest.b).c_str());
EXPECT_EQ(source.c, String8(dest.c).c_str());
}
TEST_F(Hidl2aidlTranslateTest, IFooBigStruct) {
- bool ret;
hidl2aidl::test::IFooBigStruct dest;
hidl2aidl::test::V1_1::IFoo::BigStruct source;
source.type = 12;
source.value = 16;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.type, dest.type);
EXPECT_EQ(source.value, dest.value);
}
TEST_F(Hidl2aidlTranslateTest, IBarInner) {
- bool ret;
hidl2aidl::test::IBarInner dest;
hidl2aidl::test::V1_0::IBar::Inner source;
source.a = 0x70000000;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
- EXPECT_EQ((int32_t)source.a, dest.a);
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<int32_t>(source.a), dest.a);
}
TEST_F(Hidl2aidlTranslateTest, UnsignedToSignedTooLarge) {
- bool ret;
hidl2aidl::test::IBarInner dest;
hidl2aidl::test::V1_0::IBar::Inner source;
// source.a is uint32_t, dest.a is int32_t
source.a = 0xf0000000;
- ret = h2a::translate(source, &dest);
- EXPECT_FALSE(ret);
- EXPECT_NE((int32_t)source.a, dest.a);
+ ASSERT_FALSE(h2a::translate(source, &dest));
+ EXPECT_NE(static_cast<int32_t>(source.a), dest.a);
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarByte) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.a(8);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a(), dest.get<hidl2aidl::test::SafeUnionBar::a>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarInt64) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.b(25000);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
- EXPECT_EQ(source.b(), (uint64_t)dest.get<hidl2aidl::test::SafeUnionBar::b>());
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<int64_t>(source.b()), dest.get<hidl2aidl::test::SafeUnionBar::b>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarInnerStructBar) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
hidl2aidl::test::V1_2::SafeUnionBar::InnerStructBar inner;
inner.x = 8;
inner.z = 12;
source.innerStructBar(inner);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.innerStructBar().x,
dest.get<hidl2aidl::test::SafeUnionBar::innerStructBar>().x);
EXPECT_EQ(source.innerStructBar().z,
@@ -158,45 +134,120 @@
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarOnlyIn11) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
hidl2aidl::test::V1_1::OnlyIn11 onlyIn11;
onlyIn11.str = 12;
source.c(onlyIn11);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.c().str, dest.get<hidl2aidl::test::SafeUnionBar::c>().str);
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarString) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.d("Hello world!");
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.d(), String8(dest.get<hidl2aidl::test::SafeUnionBar::d>()).c_str());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarFloat) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.e(3.5f);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.e(), dest.get<hidl2aidl::test::SafeUnionBar::e>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarDouble) {
- bool ret;
hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.f(3e10);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.f(), dest.get<hidl2aidl::test::SafeUnionBar::f>());
}
+TEST_F(Hidl2aidlTranslateTest, ArrayFoo) {
+ hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.a[0] = 42;
+ source.a[1] = 8;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ ASSERT_EQ(12u, dest.a.size());
+ EXPECT_EQ(source.a[0], dest.a[0]);
+ EXPECT_EQ(source.a[1], dest.a[1]);
+ EXPECT_EQ(source.a[2], dest.a[2]);
+ EXPECT_EQ(source.a[11], dest.a[11]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooEmpty) {
+ hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(12u, dest.a.size());
+ EXPECT_EQ(0, dest.a[0]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooEnum) {
+ hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.c[0] = hidl2aidl::test::V1_1::Value::A;
+ source.c[1] = hidl2aidl::test::V1_1::Value::B;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<hidl2aidl::test::Value>(source.c[0]), dest.c[0]);
+ EXPECT_EQ(static_cast<hidl2aidl::test::Value>(source.c[1]), dest.c[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooString) {
+ hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.d[0] = "hello";
+ source.d[1] = "world";
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.d[0], String8(dest.d[0]).c_str());
+ EXPECT_EQ(source.d[1], String8(dest.d[1]).c_str());
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFoo) {
+ hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.a = {42, 8};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.a[0], dest.a[0]);
+ EXPECT_EQ(source.a[1], dest.a[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooEmpty) {
+ hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(0u, dest.a.size());
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooUnsigned) {
+ hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ // source.a is uint32_t, dest.a is int32_t
+ source.b = {12, 0xf0000000};
+ ASSERT_FALSE(h2a::translate(source, &dest));
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooEnum) {
+ hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.c = {hidl2aidl::test::V1_1::Value::A, hidl2aidl::test::V1_1::Value::B};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<hidl2aidl::test::Value>(source.c[0]), dest.c[0]);
+ EXPECT_EQ(static_cast<hidl2aidl::test::Value>(source.c[1]), dest.c[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooString) {
+ hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.d = {"hello", "world"};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.d[0], String8(dest.d[0]).c_str());
+ EXPECT_EQ(source.d[1], String8(dest.d[1]).c_str());
+}
+
} // namespace android
diff --git a/hidl2aidl/test/translate_ndk_test.cpp b/hidl2aidl/test/translate_ndk_test.cpp
index 11b8ae7..125c236 100644
--- a/hidl2aidl/test/translate_ndk_test.cpp
+++ b/hidl2aidl/test/translate_ndk_test.cpp
@@ -23,134 +23,110 @@
namespace android {
TEST_F(Hidl2aidlTranslateTest, Onlyin10) {
- bool ret;
aidl::hidl2aidl::test::OnlyIn10 dest;
hidl2aidl::test::V1_0::OnlyIn10 source;
source.str = "Hello";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.str, dest.str);
}
TEST_F(Hidl2aidlTranslateTest, OnlyIn11) {
- bool ret;
aidl::hidl2aidl::test::OnlyIn11 dest;
hidl2aidl::test::V1_1::OnlyIn11 source;
source.str = 12;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.str, dest.str);
}
TEST_F(Hidl2aidlTranslateTest, OverrideMe) {
- bool ret;
aidl::hidl2aidl::test::OverrideMe dest;
hidl2aidl::test::V1_1::OverrideMe source;
source.a = "World";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, dest.a);
}
TEST_F(Hidl2aidlTranslateTest, Outer) {
- bool ret;
aidl::hidl2aidl::test::Outer dest;
hidl2aidl::test::V1_1::Outer source;
source.a = 12;
source.v1_0.inner.a = 16;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, dest.a);
EXPECT_EQ(source.v1_0.inner.a, dest.inner.a);
}
TEST_F(Hidl2aidlTranslateTest, OuterInner) {
- bool ret;
aidl::hidl2aidl::test::OuterInner dest;
hidl2aidl::test::V1_0::Outer::Inner source;
source.a = 12;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a, dest.a);
}
TEST_F(Hidl2aidlTranslateTest, NameCollision) {
- bool ret;
aidl::hidl2aidl::test::NameCollision dest;
hidl2aidl::test::V1_2::NameCollision source;
source.reference.reference.a = 12;
source.reference.b = "Fancy";
source.c = "Car";
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.reference.reference.a, dest.a);
EXPECT_EQ(source.reference.b, dest.b);
EXPECT_EQ(source.c, dest.c);
}
TEST_F(Hidl2aidlTranslateTest, IFooBigStruct) {
- bool ret;
aidl::hidl2aidl::test::IFooBigStruct dest;
hidl2aidl::test::V1_1::IFoo::BigStruct source;
source.type = 12;
source.value = 16;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.type, dest.type);
EXPECT_EQ(source.value, dest.value);
}
TEST_F(Hidl2aidlTranslateTest, IBarInner) {
- bool ret;
aidl::hidl2aidl::test::IBarInner dest;
hidl2aidl::test::V1_0::IBar::Inner source;
source.a = 0x70000000;
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
- EXPECT_EQ((int32_t)source.a, dest.a);
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<int32_t>(source.a), dest.a);
}
TEST_F(Hidl2aidlTranslateTest, UnsignedToSignedTooLarge) {
- bool ret;
aidl::hidl2aidl::test::IBarInner dest;
hidl2aidl::test::V1_0::IBar::Inner source;
// source.a is uint32_t, dest.a is int32_t
source.a = 0xf0000000;
- ret = h2a::translate(source, &dest);
- EXPECT_FALSE(ret);
- EXPECT_NE((int32_t)source.a, dest.a);
+ ASSERT_FALSE(h2a::translate(source, &dest));
+ EXPECT_NE(static_cast<int32_t>(source.a), dest.a);
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarByte) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.a(8);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.a(), dest.get<aidl::hidl2aidl::test::SafeUnionBar::a>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarInt64) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.b(25000);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
- EXPECT_EQ(source.b(), (uint64_t)dest.get<aidl::hidl2aidl::test::SafeUnionBar::b>());
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<int64_t>(source.b()), dest.get<aidl::hidl2aidl::test::SafeUnionBar::b>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarInnerStructBar) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
hidl2aidl::test::V1_2::SafeUnionBar::InnerStructBar inner;
inner.x = 8;
inner.z = 12;
source.innerStructBar(inner);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.innerStructBar().x,
dest.get<aidl::hidl2aidl::test::SafeUnionBar::innerStructBar>().x);
EXPECT_EQ(source.innerStructBar().z,
@@ -158,45 +134,120 @@
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarOnlyIn11) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
hidl2aidl::test::V1_1::OnlyIn11 onlyIn11;
onlyIn11.str = 12;
source.c(onlyIn11);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.c().str, dest.get<aidl::hidl2aidl::test::SafeUnionBar::c>().str);
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarString) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.d("Hello world!");
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.d(), dest.get<aidl::hidl2aidl::test::SafeUnionBar::d>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarFloat) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.e(3.5f);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.e(), dest.get<aidl::hidl2aidl::test::SafeUnionBar::e>());
}
TEST_F(Hidl2aidlTranslateTest, SafeUnionBarDouble) {
- bool ret;
aidl::hidl2aidl::test::SafeUnionBar dest;
hidl2aidl::test::V1_2::SafeUnionBar source;
source.f(3e10);
- ret = h2a::translate(source, &dest);
- EXPECT_TRUE(ret);
+ ASSERT_TRUE(h2a::translate(source, &dest));
EXPECT_EQ(source.f(), dest.get<aidl::hidl2aidl::test::SafeUnionBar::f>());
}
+TEST_F(Hidl2aidlTranslateTest, ArrayFoo) {
+ aidl::hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.a[0] = 42;
+ source.a[1] = 8;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ ASSERT_EQ(12u, dest.a.size());
+ EXPECT_EQ(source.a[0], dest.a[0]);
+ EXPECT_EQ(source.a[1], dest.a[1]);
+ EXPECT_EQ(source.a[2], dest.a[2]);
+ EXPECT_EQ(source.a[11], dest.a[11]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooEmpty) {
+ aidl::hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(12u, dest.a.size());
+ EXPECT_EQ(0, dest.a[0]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooEnum) {
+ aidl::hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.c[0] = hidl2aidl::test::V1_1::Value::A;
+ source.c[1] = hidl2aidl::test::V1_1::Value::B;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<aidl::hidl2aidl::test::Value>(source.c[0]), dest.c[0]);
+ EXPECT_EQ(static_cast<aidl::hidl2aidl::test::Value>(source.c[1]), dest.c[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, ArrayFooString) {
+ aidl::hidl2aidl::test::ArrayFoo dest;
+ hidl2aidl::test::V1_2::ArrayFoo source;
+ source.d[0] = "hello";
+ source.d[1] = "world";
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.d[0], dest.d[0]);
+ EXPECT_EQ(source.d[1], dest.d[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFoo) {
+ aidl::hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.a = {42, 8};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.a[0], dest.a[0]);
+ EXPECT_EQ(source.a[1], dest.a[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooEmpty) {
+ aidl::hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(0u, dest.a.size());
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooUnsigned) {
+ aidl::hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ // source.a is uint32_t, dest.a is int32_t
+ source.b = {12, 0xf0000000};
+ ASSERT_FALSE(h2a::translate(source, &dest));
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooEnum) {
+ aidl::hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.c = {hidl2aidl::test::V1_1::Value::A, hidl2aidl::test::V1_1::Value::B};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(static_cast<aidl::hidl2aidl::test::Value>(source.c[0]), dest.c[0]);
+ EXPECT_EQ(static_cast<aidl::hidl2aidl::test::Value>(source.c[1]), dest.c[1]);
+}
+
+TEST_F(Hidl2aidlTranslateTest, VectorFooString) {
+ aidl::hidl2aidl::test::VectorFoo dest;
+ hidl2aidl::test::V1_2::VectorFoo source;
+ source.d = {"hello", "world"};
+ ASSERT_TRUE(h2a::translate(source, &dest));
+ EXPECT_EQ(source.d[0], dest.d[0]);
+ EXPECT_EQ(source.d[1], dest.d[1]);
+}
+
} // namespace android