Pointer support and embedded types in HIDL.
* Pointers work per transaction. Don't work
across transactions.
* ref<T> in HIDL translates to T const* in C++.
* No Java support.
* Embedded types like ref<vec<vec<int32_t>>>
or vec<ref<T>> is supported. Pointers to
pointers like ref<ref<ref<T>>> is supported.
* Array of pointers and pointer to array supported.
* Pointer inside a union is NOT supported.
Test: `mma`
Test: `make hidl_test && adb sync && adb shell hidl_test`
Note that this only works with a kernel patch.
Bug: 31300815
Bug: 31349114
Change-Id: I15b74ca74a801009cc8bdc7132bd53d0185dbcbf
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 9968635..3b9320a 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -894,6 +894,27 @@
mode);
}
+void AST::emitCppResolveReferences(
+ Formatter &out,
+ const std::string &parcelObj,
+ bool parcelObjIsPointer,
+ const TypedVar *arg,
+ bool isReader,
+ Type::ErrorMode mode,
+ bool addPrefixToName) const {
+ const Type &type = arg->type();
+ if(type.needsResolveReferences()) {
+ type.emitResolveReferences(
+ out,
+ addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
+ isReader, // nameIsPointer
+ parcelObj,
+ parcelObjIsPointer,
+ isReader,
+ mode);
+ }
+}
+
status_t AST::generateProxySource(
Formatter &out, const std::string &baseName) const {
const std::string klassName = "Bp" + baseName;
@@ -954,6 +975,7 @@
out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
+ // First DFS: write all buffers and resolve pointers for parent
for (const auto &arg : method->args()) {
emitCppReaderWriter(
out,
@@ -965,6 +987,18 @@
false /* addPrefixToName */);
}
+ // Second DFS: resolve references.
+ for (const auto &arg : method->args()) {
+ emitCppResolveReferences(
+ out,
+ "_hidl_data",
+ false /* parcelObjIsPointer */,
+ arg,
+ false /* reader */,
+ Type::ErrorMode_Goto,
+ false /* addPrefixToName */);
+ }
+
out << "_hidl_err = remote()->transact("
<< superInterface->fqName().cppNamespace()
<< "::IHw"
@@ -984,6 +1018,8 @@
out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
+
+ // First DFS: write all buffers and resolve pointers for parent
for (const auto &arg : method->results()) {
emitCppReaderWriter(
out,
@@ -995,6 +1031,18 @@
true /* addPrefixToName */);
}
+ // Second DFS: resolve references.
+ for (const auto &arg : method->results()) {
+ emitCppResolveReferences(
+ out,
+ "_hidl_reply",
+ false /* parcelObjIsPointer */,
+ arg,
+ true /* reader */,
+ Type::ErrorMode_Goto,
+ true /* addPrefixToName */);
+ }
+
if (returnsValue && elidedReturn == nullptr) {
out << "if (_hidl_cb != nullptr) {\n";
out.indent();
@@ -1204,6 +1252,7 @@
declareCppReaderLocals(out, method->args(), false /* forResults */);
+ // First DFS: write buffers
for (const auto &arg : method->args()) {
emitCppReaderWriter(
out,
@@ -1215,6 +1264,18 @@
false /* addPrefixToName */);
}
+ // Second DFS: resolve references
+ for (const auto &arg : method->args()) {
+ emitCppResolveReferences(
+ out,
+ "_hidl_data",
+ false /* parcelObjIsPointer */,
+ arg,
+ true /* reader */,
+ Type::ErrorMode_Break,
+ false /* addPrefixToName */);
+ }
+
out << "if (UNLIKELY(enableInstrumentation)) {\n";
out.indent();
out << "std::vector<void *> args;\n";
@@ -1273,6 +1334,15 @@
false, /* isReader */
Type::ErrorMode_Ignore);
+ emitCppResolveReferences(
+ out,
+ "_hidl_reply",
+ true /* parcelObjIsPointer */,
+ elidedReturn,
+ false /* reader */,
+ Type::ErrorMode_Ignore,
+ false /* addPrefixToName */);
+
out << "if (UNLIKELY(enableInstrumentation)) {\n";
out.indent();
out << "std::vector<void *> results;\n";
@@ -1338,6 +1408,7 @@
out << "::android::hardware::Status::ok()"
<< ".writeToParcel(_hidl_reply);\n\n";
+ // First DFS: buffers
for (const auto &arg : method->results()) {
emitCppReaderWriter(
out,
@@ -1349,6 +1420,18 @@
false /* addPrefixToName */);
}
+ // Second DFS: resolve references
+ for (const auto &arg : method->results()) {
+ emitCppResolveReferences(
+ out,
+ "_hidl_reply",
+ true /* parcelObjIsPointer */,
+ arg,
+ false /* reader */,
+ Type::ErrorMode_Ignore,
+ false /* addPrefixToName */);
+ }
+
out << "if (UNLIKELY(enableInstrumentation)) {\n";
out.indent();
out << "std::vector<void *> results;\n";