Arrays in .hal files are now exposed to C++ as hidl_array<T, SIZE ...>
instead of as native arrays. This allows them to be copied which in turn lets
them exist in vectors. In the Java backend, vectors are limited to
one-dimensional arrays and scalar arrays are properly wrapped,
i.e. vec<uint8_t[]> => Vector<Byte[]>
Change-Id: I47524ec8423dfb41a436df36af8fa05eb8b3c0cc
Bug: 31682327
Test: hidl_test and hidl_test_java
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 6b4a01b..f84540d 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -40,6 +40,10 @@
mSizeComments.insert(mSizeComments.begin(), size->description());
}
+size_t ArrayType::countDimensions() const {
+ return mSizes.size();
+}
+
void ArrayType::addNamedTypesToSet(std::set<const FQName> &set) const {
mElementType->addNamedTypesToSet(set);
}
@@ -48,40 +52,41 @@
return true;
}
+Type *ArrayType::getElementType() const {
+ return mElementType;
+}
+
std::string ArrayType::getCppType(StorageMode mode,
std::string *extra,
bool specifyNamespaces) const {
const std::string base = mElementType->getCppType(extra, specifyNamespaces);
CHECK(extra->empty());
- size_t numArrayElements = 1;
- for (auto size : mSizes) {
- numArrayElements *= size;
+ std::string arrayType = "hidl_array<" + base;
+
+ for (size_t i = 0; i < mSizes.size(); ++i) {
+ arrayType += ", ";
+ arrayType += std::to_string(mSizes[i]);
+
+ arrayType += " /* ";
+ arrayType += mSizeComments[i];
+ arrayType += " */";
}
- std::string sizeComments = " /* " + base;
- for (auto e : mSizeComments) {
- sizeComments += "[" + e + "]";
- }
- sizeComments += " */";
+ arrayType += ">";
switch (mode) {
case StorageMode_Stack:
- {
- *extra += "[";
- *extra += std::to_string(numArrayElements);
- *extra += "]";
- *extra += sizeComments;
- return base;
- }
+ return arrayType;
case StorageMode_Argument:
+ return "const " + arrayType + "&";
+
case StorageMode_Result:
- {
- *extra += sizeComments;
- return "const " + base + "*";
- }
+ return "const " + arrayType + "*";
}
+
+ CHECK(!"Should not be here");
}
std::string ArrayType::getJavaType(
@@ -111,6 +116,10 @@
return base;
}
+std::string ArrayType::getJavaWrapperType() const {
+ return mElementType->getJavaWrapperType();
+}
+
void ArrayType::emitReaderWriter(
Formatter &out,
const std::string &name,
@@ -130,10 +139,12 @@
parcelObj + (parcelObjIsPointer ? "->" : ".");
if (isReader) {
+ std::string extra;
+
out << name
- << " = (const "
- << baseType
- << " *)"
+ << " = ("
+ << getCppResultType(&extra)
+ << ")"
<< parcelObjDeref
<< "readBuffer(&"
<< parentName
@@ -149,17 +160,18 @@
out.unindent();
out << "}\n\n";
} else {
+ size_t numArrayElements = 1;
+ for (auto size : mSizes) {
+ numArrayElements *= size;
+ }
+
out << "_hidl_err = "
<< parcelObjDeref
<< "writeBuffer("
<< name
- << ", ";
-
- for (auto size : mSizes) {
- out << size << " * ";
- }
-
- out << "sizeof("
+ << ".data(), "
+ << numArrayElements
+ << " * sizeof("
<< baseType
<< "), &"
<< parentName
@@ -224,7 +236,7 @@
mElementType->emitReaderWriterEmbedded(
out,
depth + 1,
- name + "[" + iteratorName + "]",
+ nameDeref + "data()[" + iteratorName + "]",
false /* nameIsPointer */,
parcelObj,
parcelObjIsPointer,
@@ -245,6 +257,10 @@
return mElementType->needsEmbeddedReadWrite();
}
+bool ArrayType::resultNeedsDeref() const {
+ return true;
+}
+
void ArrayType::emitJavaReaderWriter(
Formatter &out,
const std::string &parcelObj,
diff --git a/ArrayType.h b/ArrayType.h
index c0adbde..440a66c 100644
--- a/ArrayType.h
+++ b/ArrayType.h
@@ -36,7 +36,10 @@
bool isArray() const override;
+ Type *getElementType() const;
+
void addDimension(ConstantExpression *size);
+ size_t countDimensions() const;
std::string getCppType(StorageMode mode,
std::string *extra,
@@ -47,6 +50,8 @@
std::string getJavaType(
std::string *extra, bool forInitializer) const override;
+ std::string getJavaWrapperType() const override;
+
void emitReaderWriter(
Formatter &out,
const std::string &name,
@@ -68,6 +73,7 @@
const std::string &offsetText) const override;
bool needsEmbeddedReadWrite() const override;
+ bool resultNeedsDeref() const override;
void emitJavaReaderWriter(
Formatter &out,
diff --git a/VectorType.cpp b/VectorType.cpp
index 544315c..04a6ac3 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -16,6 +16,8 @@
#include "VectorType.h"
+#include "ArrayType.h"
+
#include <hidl-util/Formatter.h>
#include <android-base/logging.h>
@@ -241,14 +243,19 @@
void VectorType::emitJavaFieldInitializer(
Formatter &out, const std::string &fieldName) const {
+ std::string extra;
+ mElementType->getJavaType(&extra);
+
const std::string wrapperType = mElementType->getJavaWrapperType();
out << "final Vector<"
<< wrapperType
+ << extra
<< "> "
<< fieldName
<< " = new Vector<"
<< wrapperType
+ << extra
<< ">();\n";
}
@@ -334,8 +341,16 @@
iteratorName + " * " + std::to_string(elementSize),
true /* isReader */);
- out << fieldName
- << ".add(_hidl_vec_element);\n";
+ out << fieldName;
+
+ if (elementType->isArray()
+ && static_cast<const ArrayType *>(
+ elementType)->getElementType()->resolveToScalarType()
+ != nullptr) {
+ out << ".add(HwBlob.wrapArray(_hidl_vec_element));\n";
+ } else {
+ out << ".add(_hidl_vec_element);\n";
+ }
out.unindent();
@@ -440,7 +455,15 @@
}
bool VectorType::isJavaCompatible() const {
- return mElementType->isJavaCompatible();
+ if (!mElementType->isJavaCompatible()) {
+ return false;
+ }
+
+ if (mElementType->isArray()) {
+ return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
+ }
+
+ return true;
}
void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
diff --git a/generateJava.cpp b/generateJava.cpp
index a5bdce6..b6d1d0d 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -107,7 +107,9 @@
if (!isJavaCompatible()) {
fprintf(stderr,
"ERROR: This interface is not Java compatible. The Java backend"
- " does NOT support union types or native handles.\n");
+ " does NOT support union types nor native handles. "
+ "In addition, vectors of arrays are limited to at most "
+ "one-dimensional arrays.\n");
return UNKNOWN_ERROR;
}
diff --git a/test/java_test/hidl_test_java_native.cpp b/test/java_test/hidl_test_java_native.cpp
index f640f73..5c95948 100644
--- a/test/java_test/hidl_test_java_native.cpp
+++ b/test/java_test/hidl_test_java_native.cpp
@@ -17,6 +17,7 @@
using ::android::hardware::tests::baz::V1_0::IBaz;
using ::android::hardware::tests::baz::V1_0::IBazCallback;
+using ::android::hardware::hidl_array;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::hardware::Return;
@@ -40,31 +41,37 @@
const IBaz::Foo &foo, someOtherBaseMethod_cb _hidl_cb) override;
Return<void> someMethodWithFooArrays(
- const IBaz::Foo fooInput[2],
+ const hidl_array<IBaz::Foo, 2> &fooInput,
someMethodWithFooArrays_cb _hidl_cb) override;
Return<void> someMethodWithFooVectors(
const hidl_vec<IBaz::Foo> &fooInput,
someMethodWithFooVectors_cb _hidl_cb) override;
+ Return<void> someMethodWithVectorOfArray(
+ const IBase::VectorOfArray &in,
+ someMethodWithVectorOfArray_cb _hidl_cb) override;
+
Return<void> transpose(
const IBase::StringMatrix5x3 &in,
transpose_cb _hidl_cb) override;
Return<void> transpose2(
- const hidl_string *in /* hidl_string[5][3] */,
+ const hidl_array<hidl_string, 5, 3> &in,
transpose2_cb _hidl_cb) override;
Return<bool> someBoolMethod(bool x) override;
Return<void> someBoolArrayMethod(
- const bool x[3], someBoolArrayMethod_cb _hidl_cb) override;
+ const hidl_array<bool, 3> &x,
+ someBoolArrayMethod_cb _hidl_cb) override;
Return<void> someBoolVectorMethod(
const hidl_vec<bool> &x, someBoolVectorMethod_cb _hidl_cb) override;
Return<void> doSomethingElse(
- const int32_t param[15], doSomethingElse_cb _hidl_cb) override;
+ const hidl_array<int32_t, 15> ¶m,
+ doSomethingElse_cb _hidl_cb) override;
Return<void> doThis(float param) override;
@@ -86,7 +93,8 @@
Return<IBaz::SomeEnum> useAnEnum(IBaz::SomeEnum zzz) override;
Return<void> haveSomeStrings(
- const hidl_string array[3], haveSomeStrings_cb _hidl_cb) override;
+ const hidl_array<hidl_string, 3> &array,
+ haveSomeStrings_cb _hidl_cb) override;
Return<void> haveAStringVec(
const hidl_vec<hidl_string>& vector,
@@ -110,11 +118,26 @@
static std::string to_string(const IBase::StringMatrix5x3 &M);
static std::string to_string(const IBase::StringMatrix3x5 &M);
-template<class T>
-static std::string array_to_string(const T *array, size_t size) {
+template<typename T>
+static std::string to_string(const hidl_vec<T> &vec) {
std::string out;
out = "[";
- for (size_t i = 0; i < size; ++i) {
+ for (size_t i = 0; i < vec.size(); ++i) {
+ if (i > 0) {
+ out += ", ";
+ }
+ out += to_string(vec[i]);
+ }
+ out += "]";
+
+ return out;
+}
+
+template<typename T, size_t SIZE>
+static std::string to_string(const hidl_array<T, SIZE> &array) {
+ std::string out;
+ out = "[";
+ for (size_t i = 0; i < SIZE; ++i) {
if (i > 0) {
out += ", ";
}
@@ -125,26 +148,30 @@
return out;
}
-template<class T>
-static std::string matrix_to_string(const T *array, size_t dim1, size_t dim2) {
+template<typename T, size_t SIZE1, size_t SIZE2>
+static std::string to_string(const hidl_array<T, SIZE1, SIZE2> &array) {
std::string out;
out = "[";
- for (size_t i = 0; i < dim1; ++i) {
+ for (size_t i = 0; i < SIZE1; ++i) {
if (i > 0) {
out += ", ";
}
- out += array_to_string(&array[dim2 * i], dim2);
+
+ out += "[";
+ for (size_t j = 0; j < SIZE2; ++j) {
+ if (j > 0) {
+ out += ", ";
+ }
+
+ out += to_string(array[i][j]);
+ }
+ out += "]";
}
out += "]";
return out;
}
-template<class T>
-static std::string to_string(const hidl_vec<T> &vec) {
- return array_to_string(&vec[0], vec.size());
-}
-
static std::string to_string(bool x) {
return x ? "true" : "false";
}
@@ -175,31 +202,11 @@
}
static std::string to_string(const IBase::StringMatrix5x3 &M) {
- std::string out;
- out += "[";
- for (int i = 0; i < 5; ++i) {
- if (i > 0) {
- out += ", ";
- }
- out += array_to_string(&M.s[3 * i], 3);
- }
- out += "]";
-
- return out;
+ return to_string(M.s);
}
static std::string to_string(const IBase::StringMatrix3x5 &M) {
- std::string out;
- out += "[";
- for (int i = 0; i < 3; ++i) {
- if (i > 0) {
- out += ", ";
- }
- out += array_to_string(&M.s[5 * i], 5);
- }
- out += "]";
-
- return out;
+ return to_string(M.s);
}
Return<void> Baz::someOtherBaseMethod(
@@ -213,11 +220,12 @@
}
Return<void> Baz::someMethodWithFooArrays(
- const IBaz::Foo fooInput[2], someMethodWithFooArrays_cb _hidl_cb) {
+ const hidl_array<IBaz::Foo, 2> &fooInput,
+ someMethodWithFooArrays_cb _hidl_cb) {
LOG(INFO) << "Baz::someMethodWithFooArrays "
- << array_to_string(fooInput, 2);
+ << to_string(fooInput);
- IBaz::Foo fooOutput[2];
+ hidl_array<IBaz::Foo, 2> fooOutput;
fooOutput[0] = fooInput[1];
fooOutput[1] = fooInput[0];
@@ -242,15 +250,60 @@
return Void();
}
+static std::string VectorOfArray_to_string(const IBase::VectorOfArray &in) {
+ std::string out;
+ out += "VectorOfArray(";
+
+ for (size_t i = 0; i < in.addresses.size(); ++i) {
+ if (i > 0) {
+ out += ", ";
+ }
+
+ for (size_t j = 0; j < 6; ++j) {
+ if (j > 0) {
+ out += ":";
+ }
+
+ char tmp[3];
+ sprintf(tmp, "%02x", in.addresses[i][j]);
+
+ out += tmp;
+ }
+ }
+
+ out += ")";
+
+ return out;
+}
+
+Return<void> Baz::someMethodWithVectorOfArray(
+ const IBase::VectorOfArray &in,
+ someMethodWithVectorOfArray_cb _hidl_cb) {
+ LOG(INFO) << "Baz::someMethodWithVectorOfArray "
+ << VectorOfArray_to_string(in);
+
+ IBase::VectorOfArray out;
+
+ const size_t n = in.addresses.size();
+ out.addresses.resize(n);
+
+ for (size_t i = 0; i < n; ++i) {
+ out.addresses[i] = in.addresses[n - 1 - i];
+ }
+
+ _hidl_cb(out);
+
+ return Void();
+}
+
Return<void> Baz::transpose(
const IBase::StringMatrix5x3 &in, transpose_cb _hidl_cb) {
LOG(INFO) << "Baz::transpose " << to_string(in);
IBase::StringMatrix3x5 out;
- size_t k = 0;
for (size_t i = 0; i < 3; ++i) {
- for (size_t j = 0; j < 5; ++j, ++k) {
- out.s[k] = in.s[j * 3 + i];
+ for (size_t j = 0; j < 5; ++j) {
+ out.s[i][j] = in.s[j][i];
}
}
@@ -260,18 +313,17 @@
}
Return<void> Baz::transpose2(
- const hidl_string *in /* hidl_string[5][3] */,
- transpose2_cb _hidl_cb) {
- LOG(INFO) << "Baz::transpose2 " << matrix_to_string(in, 5, 3);
+ const hidl_array<hidl_string, 5, 3> &in, transpose2_cb _hidl_cb) {
+ LOG(INFO) << "Baz::transpose2 " << to_string(in);
- hidl_string out[3][5];
+ hidl_array<hidl_string, 3, 5> out;
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 5; ++j) {
- out[i][j] = in[j * 3 + i];
+ out[i][j] = in[j][i];
}
}
- _hidl_cb(&out[0][0]);
+ _hidl_cb(out);
return Void();
}
@@ -283,7 +335,7 @@
}
Return<void> Baz::someBoolArrayMethod(
- const bool x[3], someBoolArrayMethod_cb _hidl_cb) {
+ const hidl_array<bool, 3> &x, someBoolArrayMethod_cb _hidl_cb) {
LOG(INFO) << "Baz::someBoolArrayMethod("
<< to_string(x[0])
<< ", "
@@ -292,7 +344,7 @@
<< to_string(x[2])
<< ")";
- bool out[4];
+ hidl_array<bool, 4> out;
out[0] = !x[0];
out[1] = !x[1];
out[2] = !x[2];
@@ -319,10 +371,10 @@
}
Return<void> Baz::doSomethingElse(
- const int32_t param[15], doSomethingElse_cb _hidl_cb) {
+ const hidl_array<int32_t, 15> ¶m, doSomethingElse_cb _hidl_cb) {
LOG(INFO) << "Baz::doSomethingElse(...)";
- int32_t result[32] = { 0 };
+ hidl_array<int32_t, 32> result;
for (size_t i = 0; i < 15; ++i) {
result[i] = 2 * param[i];
result[15 + i] = param[i];
@@ -410,12 +462,12 @@
}
Return<void> Baz::haveSomeStrings(
- const hidl_string array[3], haveSomeStrings_cb _hidl_cb) {
+ const hidl_array<hidl_string, 3> &array, haveSomeStrings_cb _hidl_cb) {
LOG(INFO) << "haveSomeStrings("
- << array_to_string(array, 3)
+ << to_string(array)
<< ")";
- hidl_string result[2];
+ hidl_array<hidl_string, 2> result;
result[0] = "Hello";
result[1] = "World";
@@ -514,7 +566,7 @@
}
TEST_F(HidlTest, BazSomeMethodWithFooArraysTest) {
- IBase::Foo foo[2];
+ hidl_array<IBase::Foo, 2> foo;
foo[0].x = 1;
foo[0].y.z = 2.5;
@@ -541,7 +593,7 @@
foo,
[&](const auto &result) {
EXPECT_EQ(
- array_to_string(result, 2),
+ to_string(result),
"[Foo(x = 2, "
"y = Bar(z = -2.500000, s = 'Morituri te salutant'), "
"aaa = [Bar(z = 2.000000, s = 'Alea iacta est: 0'), "
@@ -602,6 +654,30 @@
}));
}
+TEST_F(HidlTest, BazSomeMethodWithVectorOfArray) {
+ IBase::VectorOfArray in;
+ in.addresses.resize(3);
+
+ size_t k = 0;
+ for (size_t i = 0; i < in.addresses.size(); ++i) {
+ for (size_t j = 0; j < 6; ++j, ++k) {
+ in.addresses[i][j] = k;
+ }
+ }
+
+ EXPECT_OK(
+ baz->someMethodWithVectorOfArray(
+ in,
+ [&](const auto &out) {
+ EXPECT_EQ(
+ VectorOfArray_to_string(out),
+ "VectorOfArray("
+ "0c:0d:0e:0f:10:11, "
+ "06:07:08:09:0a:0b, "
+ "00:01:02:03:04:05)");
+ }));
+}
+
static std::string numberToEnglish(int x) {
static const char *const kDigits[] = {
"zero",
@@ -651,10 +727,9 @@
TEST_F(HidlTest, BazTransposeTest) {
IBase::StringMatrix5x3 in;
- int k = 0;
for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 3; ++j, ++k) {
- in.s[k] = numberToEnglish(3 * i + j + 1).c_str();
+ for (int j = 0; j < 3; ++j) {
+ in.s[i][j] = numberToEnglish(3 * i + j + 1).c_str();
}
}
@@ -670,12 +745,11 @@
}
TEST_F(HidlTest, BazTranspose2Test) {
- hidl_string in[5 * 3];
+ hidl_array<hidl_string, 5, 3> in;
- int k = 0;
for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 3; ++j, ++k) {
- in[k] = numberToEnglish(3 * i + j + 1).c_str();
+ for (int j = 0; j < 3; ++j) {
+ in[i][j] = numberToEnglish(3 * i + j + 1).c_str();
}
}
@@ -683,7 +757,7 @@
in,
[&](const auto &out) {
EXPECT_EQ(
- matrix_to_string(out, 3, 5),
+ to_string(out),
"[['one', 'four', 'seven', 'ten', 'thirteen'], "
"['two', 'five', 'eight', 'eleven', 'fourteen'], "
"['three', 'six', 'nine', 'twelve', 'fifteen']]");
@@ -697,14 +771,17 @@
}
TEST_F(HidlTest, BazSomeBoolArrayMethodTest) {
- const bool someBoolArray[3] = { true, false, true };
+ hidl_array<bool, 3> someBoolArray;
+ someBoolArray[0] = true;
+ someBoolArray[1] = false;
+ someBoolArray[2] = true;
EXPECT_OK(
baz->someBoolArrayMethod(
someBoolArray,
[&](const auto &result) {
EXPECT_EQ(
- array_to_string(result, 4),
+ to_string(result),
"[false, true, false, true]");
}));
}
@@ -743,7 +820,7 @@
}
TEST_F(HidlTest, BazDoSomethingElseMethodTest) {
- int32_t param[15];
+ hidl_array<int32_t, 15> param;
for (size_t i = 0; i < 15; ++i) {
param[i] = i;
}
@@ -753,7 +830,7 @@
param,
[&](const auto &result) {
EXPECT_EQ(
- array_to_string(result, 32),
+ to_string(result),
"[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, "
"28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, "
"1, 2]");
@@ -780,7 +857,7 @@
vec_param,
[&](const auto &result) {
EXPECT_EQ(
- array_to_string(&result[0], result.size()),
+ to_string(result),
"[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, "
"28]");
}));
@@ -798,7 +875,7 @@
}
TEST_F(HidlTest, BazHaveSomeStringsMethodTest) {
- hidl_string string_params[3];
+ hidl_array<hidl_string, 3> string_params;
string_params[0] = "one";
string_params[1] = "two";
string_params[2] = "three";
@@ -807,8 +884,7 @@
baz->haveSomeStrings(
string_params,
[&](const auto &result) {
- EXPECT_EQ(
- array_to_string(result, 2), "['Hello', 'World']");
+ EXPECT_EQ(to_string(result), "['Hello', 'World']");
}));
}
@@ -824,9 +900,7 @@
baz->haveAStringVec(
string_vec,
[&](const auto &result) {
- EXPECT_EQ(
- array_to_string(&result[0], result.size()),
- "['Hello', 'World']");
+ EXPECT_EQ(to_string(result), "['Hello', 'World']");
}));
}
diff --git a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
index 0882043..0a09447 100644
--- a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
+++ b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
@@ -202,6 +202,34 @@
return toString(M.s);
}
+ public static String toString(IBase.VectorOfArray vec) {
+ StringBuilder out = new StringBuilder();
+
+ out.append("VectorOfArray(");
+ for (int i = 0; i < vec.addresses.size(); ++i) {
+ if (i > 0) {
+ out.append(", ");
+ }
+
+ Byte[] address = vec.addresses.elementAt(i);
+
+ for (int j = 0; j < 6; ++j) {
+ if (j > 0) {
+ out.append(":");
+ }
+
+ byte b = address[j];
+ if (b < 16) {
+ out.append("0");
+ }
+ out.append(Integer.toHexString(b));
+ }
+ }
+
+ out.append(")");
+ return out.toString();
+ }
+
private void ExpectTrue(boolean x) {
if (x) {
return;
@@ -421,6 +449,28 @@
}
{
+ IBase.VectorOfArray in = new IBase.VectorOfArray();
+
+ int k = 0;
+ for (int i = 0; i < 3; ++i) {
+ Byte[] mac = new Byte[6];
+ for (int j = 0; j < 6; ++j, ++k) {
+ mac[j] = (byte)k;
+ }
+
+ in.addresses.add(mac);
+ }
+
+ IBase.VectorOfArray out = proxy.someMethodWithVectorOfArray(in);
+
+ Expect(toString(out),
+ "VectorOfArray("
+ + "0c:0d:0e:0f:10:11, "
+ + "06:07:08:09:0a:0b, "
+ + "00:01:02:03:04:05)");
+ }
+
+ {
IBase.StringMatrix5x3 in = new IBase.StringMatrix5x3();
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 3; ++j) {
@@ -554,6 +604,19 @@
return fooOutput;
}
+ public IBase.VectorOfArray someMethodWithVectorOfArray(
+ IBase.VectorOfArray in) {
+ Log.d(TAG, "Baz someMethodWithVectorOfArray " + HidlTestJava.toString(in));
+
+ IBase.VectorOfArray out = new IBase.VectorOfArray();
+ int n = in.addresses.size();
+ for (int i = 0; i < n; ++i) {
+ out.addresses.add(in.addresses.elementAt(n - i - 1));
+ }
+
+ return out;
+ }
+
public IBase.StringMatrix3x5 transpose(IBase.StringMatrix5x3 in) {
Log.d(TAG, "Baz transpose " + HidlTestJava.toString(in));
diff --git a/test/main.cpp b/test/main.cpp
index f092c85..ed4a044 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -34,6 +34,7 @@
using ::android::hardware::tests::foo::V1_0::Abc;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::hidl_array;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
@@ -41,19 +42,19 @@
using ::android::Condition;
struct FooCallback : public IFooCallback {
- FooCallback() : invokeInfo{}, mLock{}, mCond{} {}
+ FooCallback() : mLock{}, mCond{} {}
Return<void> heyItsYou(const sp<IFooCallback> &cb) override;
Return<bool> heyItsYouIsntIt(const sp<IFooCallback> &cb) override;
Return<void> heyItsTheMeaningOfLife(uint8_t tmol) override;
Return<void> reportResults(int64_t ns, reportResults_cb cb) override;
- Return<void> youBlockedMeFor(const int64_t ns[3]) override;
+ Return<void> youBlockedMeFor(const hidl_array<int64_t, 3> &ns) override;
static constexpr nsecs_t DELAY_S = 1;
static constexpr nsecs_t DELAY_NS = seconds_to_nanoseconds(DELAY_S);
static constexpr nsecs_t TOLERANCE_NS = milliseconds_to_nanoseconds(10);
static constexpr nsecs_t ONEWAY_TOLERANCE_NS = milliseconds_to_nanoseconds(1);
- InvokeInfo invokeInfo[3];
+ hidl_array<InvokeInfo, 3> invokeInfo;
Mutex mLock;
Condition mCond;
};
@@ -116,7 +117,7 @@
return Void();
}
-Return<void> FooCallback::youBlockedMeFor(const int64_t ns[3]) {
+Return<void> FooCallback::youBlockedMeFor(const hidl_array<int64_t, 3> &ns) {
for (size_t i = 0; i < 3; i++) {
invokeInfo[i].callerBlockedNs = ns[i];
}
@@ -135,7 +136,8 @@
double d) override;
Return<void> doSomethingElse(
- const int32_t param[15], doSomethingElse_cb _cb) override;
+ const hidl_array<int32_t, 15> ¶m,
+ doSomethingElse_cb _cb) override;
Return<void> doStuffAndReturnAString(
doStuffAndReturnAString_cb _cb) override;
@@ -150,12 +152,12 @@
Return<void> haveAGooberVec(const hidl_vec<Goober>& param) override;
Return<void> haveAGoober(const Goober &g) override;
- Return<void> haveAGooberArray(const Goober lots[20]) override;
+ Return<void> haveAGooberArray(const hidl_array<Goober, 20> &lots) override;
Return<void> haveATypeFromAnotherFile(const Abc &def) override;
Return<void> haveSomeStrings(
- const hidl_string array[3],
+ const hidl_array<hidl_string, 3> &array,
haveSomeStrings_cb _cb) override;
Return<void> haveAStringVec(
@@ -163,7 +165,7 @@
haveAStringVec_cb _cb) override;
Return<void> transposeMe(
- const float *in /* float[3][5] */, transposeMe_cb _cb) override;
+ const hidl_array<float, 3, 5> &in, transposeMe_cb _cb) override;
Return<void> callingDrWho(
const MultiDimensional &in,
@@ -173,7 +175,7 @@
const StringMatrix5x3 &in, transpose_cb _hidl_cb) override;
Return<void> transpose2(
- const hidl_string *in /* hidl_string[5][3] */,
+ const hidl_array<hidl_string, 5, 3> &in,
transpose2_cb _hidl_cb) override;
Return<void> thisIsNew() override;
@@ -203,10 +205,10 @@
}
Return<void> Bar::doSomethingElse(
- const int32_t param[15], doSomethingElse_cb _cb) {
+ const hidl_array<int32_t, 15> ¶m, doSomethingElse_cb _cb) {
ALOGI("SERVER(Bar) doSomethingElse(...)");
- int32_t result[32] = { 0 };
+ hidl_array<int32_t, 32> result;
for (size_t i = 0; i < 15; ++i) {
result[i] = 2 * param[i];
result[15 + i] = param[i];
@@ -253,7 +255,7 @@
if (cb != NULL) {
- nsecs_t c[3];
+ hidl_array<nsecs_t, 3> c;
ALOGI("SERVER(Bar) callMe %p calling IFooCallback::heyItsYou, " \
"should return immediately", cb.get());
c[0] = systemTime();
@@ -309,8 +311,8 @@
return Void();
}
-Return<void> Bar::haveAGooberArray(const Goober lots[20]) {
- ALOGI("SERVER(Bar) haveAGooberArray lots = %p", lots);
+Return<void> Bar::haveAGooberArray(const hidl_array<Goober, 20> & /* lots */) {
+ ALOGI("SERVER(Bar) haveAGooberArray");
return Void();
}
@@ -322,14 +324,14 @@
}
Return<void> Bar::haveSomeStrings(
- const hidl_string array[3],
+ const hidl_array<hidl_string, 3> &array,
haveSomeStrings_cb _cb) {
ALOGI("SERVER(Bar) haveSomeStrings([\"%s\", \"%s\", \"%s\"])",
array[0].c_str(),
array[1].c_str(),
array[2].c_str());
- hidl_string result[2];
+ hidl_array<hidl_string, 2> result;
result[0] = "Hello";
result[1] = "World";
@@ -357,41 +359,62 @@
return Void();
}
-static std::string FloatArray2DToString(const float *x, size_t n1, size_t n2) {
- std::string s;
- s += "[";
- for (size_t i = 0; i < n1; ++i) {
+using std::to_string;
+
+static std::string to_string(const IFoo::StringMatrix5x3 &M);
+static std::string to_string(const IFoo::StringMatrix3x5 &M);
+static std::string to_string(const hidl_string &s);
+
+template<typename T, size_t SIZE1, size_t SIZE2>
+static std::string to_string(const hidl_array<T, SIZE1, SIZE2> &array) {
+ std::string out;
+ out = "[";
+ for (size_t i = 0; i < SIZE1; ++i) {
if (i > 0) {
- s += ", ";
+ out += ", ";
}
- s += "[";
- for (size_t j = 0; j < n2; ++j) {
+ out += "[";
+ for (size_t j = 0; j < SIZE2; ++j) {
if (j > 0) {
- s += ", ";
+ out += ", ";
}
- s += std::to_string(x[i * n2 + j]);
- }
- s += "]";
- }
- s += "]";
- return s;
+ out += to_string(array[i][j]);
+ }
+ out += "]";
+ }
+ out += "]";
+
+ return out;
+}
+
+static std::string to_string(const IFoo::StringMatrix5x3 &M) {
+ return to_string(M.s);
+}
+
+static std::string to_string(const IFoo::StringMatrix3x5 &M) {
+ return to_string(M.s);
+}
+
+static std::string to_string(const hidl_string &s) {
+ return std::string("'") + s.c_str() + "'";
}
Return<void> Bar::transposeMe(
- const float *in /* float[3][5] */, transposeMe_cb _cb) {
- ALOGI("SERVER(Bar) transposeMe(%s)",
- FloatArray2DToString(in, 3, 5).c_str());
+ const hidl_array<float, 3, 5> &in, transposeMe_cb _cb) {
+ ALOGI("SERVER(Bar) transposeMe(%s)", to_string(in).c_str());
- float out[5][3];
+ hidl_array<float, 5, 3> out;
for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 3; ++j) {
- out[i][j] = in[5 * j + i];
+ out[i][j] = in[j][i];
}
}
- _cb(&out[0][0]);
+ ALOGI("SERVER(Bar) transposeMe returning %s", to_string(out).c_str());
+
+ _cb(out);
return Void();
}
@@ -427,7 +450,7 @@
s += ", ";
}
- s += QuuxToString(val.quuxMatrix[k]);
+ s += QuuxToString(val.quuxMatrix[i][j]);
}
}
s += "]";
@@ -442,13 +465,10 @@
ALOGI("SERVER(Bar) callingDrWho(%s)", MultiDimensionalToString(in).c_str());
MultiDimensional out;
- size_t k = 0;
for (size_t i = 0; i < 5; ++i) {
- for (size_t j = 0; j < 3; ++j, ++k) {
- size_t k_prime = (4 - i) * 3 + (2 - j);
-
- out.quuxMatrix[k].first = in.quuxMatrix[k_prime].last;
- out.quuxMatrix[k].last = in.quuxMatrix[k_prime].first;
+ for (size_t j = 0; j < 3; ++j) {
+ out.quuxMatrix[i][j].first = in.quuxMatrix[4 - i][2 - j].last;
+ out.quuxMatrix[i][j].last = in.quuxMatrix[4 - i][2 - j].first;
}
}
@@ -457,62 +477,13 @@
return Void();
}
-using std::to_string;
-
-static std::string to_string(const IFoo::StringMatrix5x3 &M);
-static std::string to_string(const IFoo::StringMatrix3x5 &M);
-static std::string to_string(const hidl_string &s);
-
-template<class T>
-static std::string array_to_string(const T *array, size_t size) {
- std::string out;
- out = "[";
- for (size_t i = 0; i < size; ++i) {
- if (i > 0) {
- out += ", ";
- }
- out += to_string(array[i]);
- }
- out += "]";
-
- return out;
-}
-
-template<class T>
-static std::string matrix_to_string(const T *array, size_t dim1, size_t dim2) {
- std::string out;
- out = "[";
- for (size_t i = 0; i < dim1; ++i) {
- if (i > 0) {
- out += ", ";
- }
- out += array_to_string(&array[dim2 * i], dim2);
- }
- out += "]";
-
- return out;
-}
-
-static std::string to_string(const IFoo::StringMatrix5x3 &M) {
- return matrix_to_string(M.s, 5, 3);
-}
-
-static std::string to_string(const IFoo::StringMatrix3x5 &M) {
- return matrix_to_string(M.s, 3, 5);
-}
-
-static std::string to_string(const hidl_string &s) {
- return std::string("'") + s.c_str() + "'";
-}
-
Return<void> Bar::transpose(const StringMatrix5x3 &in, transpose_cb _hidl_cb) {
LOG(INFO) << "SERVER(Bar) transpose " << to_string(in);
StringMatrix3x5 out;
- size_t k = 0;
for (size_t i = 0; i < 3; ++i) {
- for (size_t j = 0; j < 5; ++j, ++k) {
- out.s[k] = in.s[j * 3 + i];
+ for (size_t j = 0; j < 5; ++j) {
+ out.s[i][j] = in.s[j][i];
}
}
@@ -522,17 +493,17 @@
}
Return<void> Bar::transpose2(
- const hidl_string *in /* hidl_string[5][3] */, transpose2_cb _hidl_cb) {
- LOG(INFO) << "SERVER(Bar) transpose2 " << matrix_to_string(in, 5, 3);
+ const hidl_array<hidl_string, 5, 3> &in, transpose2_cb _hidl_cb) {
+ LOG(INFO) << "SERVER(Bar) transpose2 " << to_string(in);
- hidl_string out[3][5];
+ hidl_array<hidl_string, 3, 5> out;
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 5; ++j) {
- out[i][j] = in[j * 3 + i];
+ out[i][j] = in[j][i];
}
}
- _hidl_cb(&out[0][0]);
+ _hidl_cb(out);
return Void();
}
@@ -687,7 +658,7 @@
TEST_F(HidlTest, FooDoSomethingElseTest) {
ALOGI("CLIENT call doSomethingElse");
- int32_t param[15];
+ hidl_array<int32_t, 15> param;
for (size_t i = 0; i < sizeof(param) / sizeof(param[0]); ++i) {
param[i] = i;
}
@@ -759,7 +730,7 @@
fooCb->reportResults(reportResultsNs,
[&](int64_t timeLeftNs,
- const IFooCallback::InvokeInfo invokeResults[3]) {
+ const hidl_array<IFooCallback::InvokeInfo, 3> &invokeResults) {
ALOGI("CLIENT: FooCallback::reportResults() is returning data.");
ALOGI("CLIENT: Waited for %" PRId64 " milliseconds.",
nanoseconds_to_milliseconds(reportResultsNs - timeLeftNs));
@@ -806,7 +777,7 @@
ALOGI("CLIENT haveaGoober returned.");
ALOGI("CLIENT call haveAGooberArray.");
- IFoo::Goober gooberArrayParam[20];
+ hidl_array<IFoo::Goober, 20> gooberArrayParam;
EXPECT_OK(foo->haveAGooberArray(gooberArrayParam));
ALOGI("CLIENT haveAGooberArray returned.");
}
@@ -825,7 +796,7 @@
TEST_F(HidlTest, FooHaveSomeStringsTest) {
ALOGI("CLIENT call haveSomeStrings.");
- hidl_string stringArrayParam[3];
+ hidl_array<hidl_string, 3> stringArrayParam;
stringArrayParam[0] = "What";
stringArrayParam[1] = "a";
stringArrayParam[2] = "disaster";
@@ -845,7 +816,7 @@
}
TEST_F(HidlTest, FooTransposeMeTest) {
- float in[3][5];
+ hidl_array<float, 3, 5> in;
float k = 1.0f;
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 5; ++j, ++k) {
@@ -853,18 +824,17 @@
}
}
- ALOGI("CLIENT call transposeMe(%s).",
- FloatArray2DToString(&in[0][0], 3, 5).c_str());
+ ALOGI("CLIENT call transposeMe(%s).", to_string(in).c_str());
EXPECT_OK(foo->transposeMe(
- &in[0][0],
+ in,
[&](const auto &out) {
ALOGI("CLIENT transposeMe returned %s.",
- FloatArray2DToString(out, 5, 3).c_str());
+ to_string(out).c_str());
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 5; ++j) {
- EXPECT_EQ(out[3 * j + i], in[i][j]);
+ EXPECT_EQ(out[j][i], in[i][j]);
}
}
}));
@@ -876,8 +846,8 @@
size_t k = 0;
for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 3; ++j, ++k) {
- in.quuxMatrix[k].first = ("First " + std::to_string(k)).c_str();
- in.quuxMatrix[k].last = ("Last " + std::to_string(15-k)).c_str();
+ in.quuxMatrix[i][j].first = ("First " + std::to_string(k)).c_str();
+ in.quuxMatrix[i][j].last = ("Last " + std::to_string(15-k)).c_str();
}
}
@@ -893,15 +863,13 @@
size_t k = 0;
for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 3; ++j, ++k) {
- size_t k_prime = (4 - i) * 3 + (2 - j);
+ EXPECT_STREQ(
+ out.quuxMatrix[i][j].first.c_str(),
+ in.quuxMatrix[4 - i][2 - j].last.c_str());
EXPECT_STREQ(
- out.quuxMatrix[k].first.c_str(),
- in.quuxMatrix[k_prime].last.c_str());
-
- EXPECT_STREQ(
- out.quuxMatrix[k].last.c_str(),
- in.quuxMatrix[k_prime].first.c_str());
+ out.quuxMatrix[i][j].last.c_str(),
+ in.quuxMatrix[4 - i][2 - j].first.c_str());
}
}
}));
@@ -956,10 +924,9 @@
TEST_F(HidlTest, FooTransposeTest) {
IFoo::StringMatrix5x3 in;
- int k = 0;
for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 3; ++j, ++k) {
- in.s[k] = numberToEnglish(3 * i + j + 1).c_str();
+ for (int j = 0; j < 3; ++j) {
+ in.s[i][j] = numberToEnglish(3 * i + j + 1).c_str();
}
}
@@ -975,12 +942,11 @@
}
TEST_F(HidlTest, FooTranspose2Test) {
- hidl_string in[5 * 3];
+ hidl_array<hidl_string, 5, 3> in;
- int k = 0;
for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 3; ++j, ++k) {
- in[k] = numberToEnglish(3 * i + j + 1).c_str();
+ for (int j = 0; j < 3; ++j) {
+ in[i][j] = numberToEnglish(3 * i + j + 1).c_str();
}
}
@@ -988,7 +954,7 @@
in,
[&](const auto &out) {
EXPECT_EQ(
- matrix_to_string(out, 3, 5),
+ to_string(out),
"[['one', 'four', 'seven', 'ten', 'thirteen'], "
"['two', 'five', 'eight', 'eleven', 'fourteen'], "
"['three', 'six', 'nine', 'twelve', 'fifteen']]");