Merge "Revert "Add compile time test to c2hal""
diff --git a/AST.h b/AST.h
index f82a9ba..9a3670c 100644
--- a/AST.h
+++ b/AST.h
@@ -146,6 +146,11 @@
void getPackageAndVersionComponents(
std::vector<std::string> *components, bool cpp_compatible) const;
+ static void generateCppPackageInclude(
+ Formatter &out,
+ const FQName &package,
+ const std::string &klass);
+
std::string makeHeaderGuard(const std::string &baseName) const;
void enterLeaveNamespace(Formatter &out, bool enter) const;
@@ -161,41 +166,26 @@
status_t generateTypeSource(
Formatter &out, const std::string &ifaceName) const;
- enum MethodLocation {
- PROXY_HEADER,
- STUB_HEADER,
- IMPL_HEADER,
- IMPL_SOURCE,
- PASSTHROUGH_HEADER
- };
+ // a method, and in which interface is it originally defined.
+ // be careful of the case where method.isHidlReserved(), where interface
+ // is effectively useless.
+ using MethodGenerator = std::function<status_t(const Method *, const Interface *)>;
status_t generateStubImplHeader(const std::string &outputPath) const;
status_t generateStubImplSource(const std::string &outputPath) const;
- status_t generateMethods(Formatter &out,
- const std::string &className,
- MethodLocation type,
- bool specifyNamespaces) const;
+ status_t generateMethods(Formatter &out, MethodGenerator gen) const;
status_t generateStubMethod(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const;
- status_t generateProxyDeclaration(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const;
- status_t generateStubImplDeclaration(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const;
+ const Method *method) const;
status_t generateStubImplMethod(Formatter &out,
const std::string &className,
- const Method *method,
- bool specifyNamespaces) const;
+ const Method *method) const;
status_t generatePassthroughMethod(Formatter &out,
+ const Method *method) const;
+ status_t generateProxyMethodSource(Formatter &out,
const std::string &className,
const Method *method,
- bool specifyNamespaces) const;
+ const Interface *superInterface) const;
void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const;
@@ -221,12 +211,13 @@
SYNC_CALLBACK_EXIT,
ASYNC_CALLBACK_ENTRY,
ASYNC_CALLBACK_EXIT,
+ PASSTHROUGH_ENTRY,
+ PASSTHROUGH_EXIT,
};
status_t generateCppInstrumentationCall(
Formatter &out,
InstrumentationEvent event,
- const Interface *iface,
const Method *method) const;
void declareCppReaderLocals(
diff --git a/CompoundType.cpp b/CompoundType.cpp
index eb5d083..870402b 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -758,7 +758,7 @@
}
status_t CompoundType::emitVtsTypeDeclarations(Formatter &out) const {
- out << "name: \"" << localName() << "\"\n";
+ out << "name: \"" << fullName() << "\"\n";
out << "type: " << getVtsType() << "\n";
// Emit declaration for each subtype.
@@ -813,7 +813,7 @@
status_t CompoundType::emitVtsAttributeType(Formatter &out) const {
out << "type: " << getVtsType() << "\n";
- out << "predefined_type: \"" << localName() << "\"\n";
+ out << "predefined_type: \"" << fullName() << "\"\n";
return OK;
}
diff --git a/Coordinator.cpp b/Coordinator.cpp
index 2e17b61..57da8bb 100644
--- a/Coordinator.cpp
+++ b/Coordinator.cpp
@@ -226,8 +226,7 @@
packagePath.append(packageSuffix.substr(startPos));
packagePath.append("/");
- CHECK_EQ(fqName.version().find('@'), 0u);
- packagePath.append(fqName.version().substr(1));
+ packagePath.append(fqName.version());
packagePath.append("/");
return packagePath;
@@ -296,7 +295,7 @@
for (const auto &fileName : fileNames) {
FQName subFQName(
- package.package() + package.version() + "::" + fileName);
+ package.package() + package.atVersion() + "::" + fileName);
if (!subFQName.isValid()) {
LOG(WARNING)
@@ -304,7 +303,7 @@
<< fileName
<< "' in package "
<< package.package()
- << package.version();
+ << package.atVersion();
continue;
}
diff --git a/EnumType.cpp b/EnumType.cpp
index 1905a3e..27c0075 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -295,7 +295,7 @@
}
status_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
- out << "name: \"" << localName() << "\"\n";
+ out << "name: \"" << fullName() << "\"\n";
out << "type: " << getVtsType() << "\n";
out << "enum_value: {\n";
out.indent();
@@ -334,7 +334,7 @@
status_t EnumType::emitVtsAttributeType(Formatter &out) const {
out << "type: " << getVtsType() << "\n";
- out << "predefined_type: \"" << localName() << "\"\n";
+ out << "predefined_type: \"" << fullName() << "\"\n";
return OK;
}
diff --git a/FQName.cpp b/FQName.cpp
index 0169e0c..df0515c 100644
--- a/FQName.cpp
+++ b/FQName.cpp
@@ -24,18 +24,21 @@
#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
-#define RE_VERSION "@[0-9]+[.][0-9]+"
+#define RE_MAJOR "[0-9]+"
+#define RE_MINOR "[0-9]+"
-static const std::regex kRE1("(" RE_PATH ")(" RE_VERSION ")?::(" RE_PATH ")");
-static const std::regex kRE2("(" RE_VERSION ")::(" RE_PATH ")");
-static const std::regex kRE3("(" RE_PATH ")(" RE_VERSION ")");
+static const std::regex kRE1("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")?::(" RE_PATH ")");
+static const std::regex kRE2("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
+static const std::regex kRE3("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")");
static const std::regex kRE4("(" RE_COMPONENT ")([.]" RE_COMPONENT ")+");
static const std::regex kRE5("(" RE_COMPONENT ")");
-static const std::regex kRE6("(" RE_PATH ")(" RE_VERSION ")?::(" RE_PATH "):(" RE_COMPONENT ")");
-static const std::regex kRE7("(" RE_VERSION ")::(" RE_PATH "):(" RE_COMPONENT ")");
+static const std::regex kRE6("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")?::(" RE_PATH "):(" RE_COMPONENT ")");
+static const std::regex kRE7("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
static const std::regex kRE8("(" RE_PATH "):(" RE_COMPONENT ")");
+static const std::regex kREVer("(" RE_MAJOR ")[.](" RE_MINOR ")");
+
namespace android {
FQName::FQName()
@@ -57,16 +60,17 @@
: mValid(true),
mIsIdentifier(false),
mPackage(package),
- mVersion(version),
mName(name),
mValueName(valueName) {
+ setVersion(version);
}
FQName::FQName(const FQName& other)
: mValid(other.mValid),
mIsIdentifier(other.mIsIdentifier),
mPackage(other.mPackage),
- mVersion(other.mVersion),
+ mMajor(other.mMajor),
+ mMinor(other.mMinor),
mName(other.mName),
mValueName(other.mValueName) {
}
@@ -86,7 +90,7 @@
}
bool FQName::isFullyQualified() const {
- return !mPackage.empty() && !mVersion.empty() && !mName.empty();
+ return !mPackage.empty() && !version().empty() && !mName.empty();
}
bool FQName::isValidValueName() const {
@@ -96,46 +100,52 @@
bool FQName::setTo(const std::string &s) {
mPackage.clear();
- mVersion.clear();
+ mMajor.clear();
+ mMinor.clear();
mName.clear();
mValid = true;
std::smatch match;
if (std::regex_match(s, match, kRE1)) {
+ CHECK_EQ(match.size(), 5u);
+
+ mPackage = match.str(1);
+ mMajor = match.str(2);
+ mMinor = match.str(3);
+ mName = match.str(4);
+ } else if (std::regex_match(s, match, kRE2)) {
+ CHECK_EQ(match.size(), 4u);
+
+ mMajor = match.str(1);
+ mMinor = match.str(2);
+ mName = match.str(3);
+ } else if (std::regex_match(s, match, kRE3)) {
CHECK_EQ(match.size(), 4u);
mPackage = match.str(1);
- mVersion = match.str(2);
- mName = match.str(3);
- } else if (std::regex_match(s, match, kRE2)) {
- CHECK_EQ(match.size(), 3u);
-
- mVersion = match.str(1);
- mName = match.str(2);
- } else if (std::regex_match(s, match, kRE3)) {
- CHECK_EQ(match.size(), 3u);
-
- mPackage = match.str(1);
- mVersion = match.str(2);
+ mMajor = match.str(2);
+ mMinor = match.str(3);
} else if (std::regex_match(s, match, kRE4)) {
mName = match.str(0);
} else if (std::regex_match(s, match, kRE5)) {
mIsIdentifier = true;
mName = match.str(0);
} else if (std::regex_match(s, match, kRE6)) {
- CHECK_EQ(match.size(), 5u);
+ CHECK_EQ(match.size(), 6u);
mPackage = match.str(1);
- mVersion = match.str(2);
+ mMajor = match.str(2);
+ mMinor = match.str(3);
+ mName = match.str(4);
+ mValueName = match.str(5);
+ } else if (std::regex_match(s, match, kRE7)) {
+ CHECK_EQ(match.size(), 5u);
+
+ mMajor = match.str(1);
+ mMinor = match.str(2);
mName = match.str(3);
mValueName = match.str(4);
- } else if (std::regex_match(s, match, kRE7)) {
- CHECK_EQ(match.size(), 4u);
-
- mVersion = match.str(1);
- mName = match.str(2);
- mValueName = match.str(3);
} else if (std::regex_match(s, match, kRE8)) {
CHECK_EQ(match.size(), 3u);
@@ -158,7 +168,33 @@
}
std::string FQName::version() const {
- return mVersion;
+ CHECK(mMajor.empty() == mMinor.empty());
+ if (mMajor.empty() && mMinor.empty()) {
+ return "";
+ }
+ return mMajor + "." + mMinor;
+}
+
+std::string FQName::atVersion() const {
+ std::string v = version();
+ return v.empty() ? "" : ("@" + v);
+}
+
+void FQName::setVersion(const std::string &v) {
+ if (v.empty()) {
+ mMajor.clear();
+ mMinor.clear();
+ return;
+ }
+ std::smatch match;
+ if (std::regex_match(v, match, kREVer)) {
+ CHECK_EQ(match.size(), 3u);
+
+ mMajor = match.str(1);
+ mMinor = match.str(2);
+ } else {
+ mValid = false;
+ }
}
std::string FQName::name() const {
@@ -180,7 +216,7 @@
}
FQName FQName::typeName() const {
- return FQName(mPackage, mVersion, mName);
+ return FQName(mPackage, version(), mName);
}
void FQName::applyDefaults(
@@ -190,8 +226,8 @@
mPackage = defaultPackage;
}
- if (mVersion.empty()) {
- mVersion = defaultVersion;
+ if (version().empty()) {
+ setVersion(defaultVersion);
}
}
@@ -200,9 +236,9 @@
std::string out;
out.append(mPackage);
- out.append(mVersion);
+ out.append(atVersion());
if (!mName.empty()) {
- if (!mPackage.empty() || !mVersion.empty()) {
+ if (!mPackage.empty() || !version().empty()) {
out.append("::");
}
out.append(mName);
@@ -252,7 +288,7 @@
return *this;
}
- return FQName(mPackage, mVersion, mName.substr(0, idx));
+ return FQName(mPackage, version(), mName.substr(0, idx));
}
std::string FQName::tokenName() const {
@@ -336,25 +372,11 @@
}
std::string FQName::getPackageMajorVersion() const {
- const std::string packageVersion = version();
- CHECK(packageVersion[0] == '@');
- const size_t dotPos = packageVersion.find('.');
- CHECK(dotPos != std::string::npos);
- return packageVersion.substr(1, dotPos - 1);
+ return mMajor;
}
std::string FQName::getPackageMinorVersion() const {
- const std::string packageVersion = version();
- CHECK(packageVersion[0] == '@');
- const size_t dotPos = packageVersion.find('.');
- CHECK(dotPos != std::string::npos);
- return packageVersion.substr(dotPos + 1);
-}
-
-std::string FQName::getPackageFullVersion() const {
- const std::string packageVersion = version();
- CHECK_GT(packageVersion.length(), 1u);
- return packageVersion.substr(1);
+ return mMinor;
}
bool FQName::endsWith(const FQName &other) const {
diff --git a/FQName.h b/FQName.h
index 391ba3d..a781157 100644
--- a/FQName.h
+++ b/FQName.h
@@ -47,6 +47,9 @@
const std::string &defaultVersion);
std::string package() const;
+ // Return version in the form "@1.0" if it is present, otherwise empty string.
+ std::string atVersion() const;
+ // Return version in the form "1.0" if it is present, otherwise empty string.
std::string version() const;
// The next two methods return the name part of the FQName, that is, the
@@ -147,16 +150,16 @@
std::string getPackageMinorVersion() const;
- // Returns the version of the package by cutting off the leading '@' prefix.
- std::string getPackageFullVersion() const;
-
private:
bool mValid;
bool mIsIdentifier;
std::string mPackage;
- std::string mVersion;
+ std::string mMajor;
+ std::string mMinor;
std::string mName;
std::string mValueName;
+
+ void setVersion(const std::string &v);
};
} // namespace android
diff --git a/Interface.cpp b/Interface.cpp
index d348101..f03f3aa 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -252,11 +252,21 @@
out.unindent();
out << "}\n\n";
} else {
+ out << "if (" << name << " == nullptr) {\n";
+ out.indent();
+ out << "_hidl_err = ";
+ out << parcelObjDeref
+ << "writeStrongBinder(nullptr);\n";
+ out.unindent();
+ out << "} else {\n";
+ out.indent();
out << "_hidl_err = "
<< parcelObjDeref
<< "writeStrongBinder("
<< name
<< "->toBinder());\n";
+ out.unindent();
+ out << "}\n";
handleError(out, mode);
}
diff --git a/Method.h b/Method.h
index 7e711f0..4f5163d 100644
--- a/Method.h
+++ b/Method.h
@@ -62,8 +62,8 @@
size_t getSerialId() const;
void generateCppSignature(Formatter &out,
- const std::string &className,
- bool specifyNamespaces) const;
+ const std::string &className = "",
+ bool specifyNamespaces = true) const;
static std::string GetArgSignature(const std::vector<TypedVar *> &args,
bool specifyNamespaces);
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 69ded55..fdc5f90 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -78,6 +78,25 @@
return guard;
}
+// static
+void AST::generateCppPackageInclude(
+ Formatter &out,
+ const FQName &package,
+ const std::string &klass) {
+
+ out << "#include <";
+
+ std::vector<std::string> components;
+ package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
+
+ for (const auto &component : components) {
+ out << component << "/";
+ }
+
+ out << klass
+ << ".h>\n";
+}
+
void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
std::vector<std::string> packageComponents;
getPackageAndVersionComponents(
@@ -130,18 +149,7 @@
out << "#define " << guard << "\n\n";
for (const auto &item : mImportedNames) {
- out << "#include <";
-
- std::vector<std::string> components;
- item.getPackageAndVersionComponents(
- &components, false /* cpp_compatible */);
-
- for (const auto &component : components) {
- out << component << "/";
- }
-
- out << item.name()
- << ".h>\n";
+ generateCppPackageInclude(out, item, item.name());
}
if (!mImportedNames.empty()) {
@@ -341,36 +349,16 @@
out << "#ifndef " << guard << "\n";
out << "#define " << guard << "\n\n";
- std::vector<std::string> packageComponents;
- getPackageAndVersionComponents(
- &packageComponents, false /* cpp_compatible */);
+ generateCppPackageInclude(out, mPackage, ifaceName);
- out << "#include <";
- for (const auto &component : packageComponents) {
- out << component << "/";
- }
- out << ifaceName << ".h>\n\n";
+ out << "\n";
for (const auto &item : mImportedNames) {
if (item.name() == "types") {
continue;
}
- out << "#include <";
-
- std::vector<std::string> components;
- item.getPackageAndVersionComponents(
- &components, false /* cpp_compatible */);
-
- for (const auto &component : components) {
- out << component << "/";
- }
-
- const std::string itemBaseName = item.getInterfaceBaseName();
-
- out << "Bn"
- << itemBaseName
- << ".h>\n";
+ generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
}
out << "\n";
@@ -416,14 +404,10 @@
}
status_t AST::generateStubMethod(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const {
+ const Method *method) const {
out << "inline ";
- method->generateCppSignature(out,
- className,
- specifyNamespaces);
+ method->generateCppSignature(out);
const bool returnsValue = !method->results().empty();
const TypedVar *elidedReturn = method->canElideCallback();
@@ -456,25 +440,9 @@
return OK;
}
-status_t AST::generateProxyDeclaration(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const {
-
- method->generateCppSignature(out,
- className,
- specifyNamespaces);
- out << " override;\n";
-
- return OK;
-}
-
-
status_t AST::generatePassthroughMethod(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const {
- method->generateCppSignature(out, className, specifyNamespaces);
+ const Method *method) const {
+ method->generateCppSignature(out);
out << " {\n";
out.indent();
@@ -486,14 +454,21 @@
generateCheckNonNull(out, "_hidl_cb");
}
- out << "return ";
+ generateCppInstrumentationCall(
+ out,
+ InstrumentationEvent::PASSTHROUGH_ENTRY,
+ method);
+
+ out << "auto _hidl_return = ";
if (method->isOneway()) {
out << "addOnewayTask([this";
for (const auto &arg : method->args()) {
out << ", " << arg->name();
}
- out << "] {this->";
+ out << "] {\n";
+ out.indent();
+ out << "this->";
}
out << "mImpl->"
@@ -515,12 +490,19 @@
out << "_hidl_cb";
}
- out << ")";
+ out << ");\n\n";
+
+ generateCppInstrumentationCall(
+ out,
+ InstrumentationEvent::PASSTHROUGH_EXIT,
+ method);
if (method->isOneway()) {
- out << ";})";
+ out.unindent();
+ out << "});\n";
}
- out << ";\n";
+
+ out << "return _hidl_return;\n";
out.unindent();
out << "}\n";
@@ -528,11 +510,7 @@
return OK;
}
-status_t AST::generateMethods(
- Formatter &out,
- const std::string &className,
- MethodLocation type,
- bool specifyNamespaces) const {
+status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
const Interface *iface = mRootScope->getInterface();
@@ -550,42 +528,7 @@
<< " follow.\n";
prevIterface = superInterface;
}
- status_t err;
- switch(type) {
- case STUB_HEADER:
- err = generateStubMethod(out,
- className,
- method,
- specifyNamespaces);
- break;
- case PROXY_HEADER:
- err = generateProxyDeclaration(out,
- className,
- method,
- specifyNamespaces);
- break;
- case IMPL_HEADER:
- err = generateStubImplDeclaration(out,
- className,
- method,
- specifyNamespaces);
- break;
- case IMPL_SOURCE:
- err = generateStubImplMethod(out,
- className,
- method,
- specifyNamespaces);
- break;
- case PASSTHROUGH_HEADER:
- err = generatePassthroughMethod(out,
- className,
- method,
- specifyNamespaces);
- break;
- default:
- LOG(ERROR) << "Unkown method type: " << type;
- err = UNKNOWN_ERROR;
- }
+ status_t err = gen(method, superInterface);
if (err != OK) {
return err;
@@ -628,15 +571,8 @@
out << "#ifndef " << guard << "\n";
out << "#define " << guard << "\n\n";
- std::vector<std::string> packageComponents;
- getPackageAndVersionComponents(
- &packageComponents, false /* cpp_compatible */);
-
- out << "#include <";
- for (const auto &component : packageComponents) {
- out << component << "/";
- }
- out << "IHw" << baseName << ".h>\n\n";
+ generateCppPackageInclude(out, mPackage, "IHw" + baseName);
+ out << "\n";
enterLeaveNamespace(out, true /* enter */);
out << "\n";
@@ -664,10 +600,9 @@
out.unindent();
out.unindent();
- status_t err = generateMethods(out,
- "" /* class name */,
- MethodLocation::STUB_HEADER,
- true /* specify namespaces */);
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+ return generateStubMethod(out, method);
+ });
if (err != OK) {
return err;
@@ -719,11 +654,8 @@
getPackageAndVersionComponents(
&packageComponents, false /* cpp_compatible */);
- out << "#include <";
- for (const auto &component : packageComponents) {
- out << component << "/";
- }
- out << "IHw" << baseName << ".h>\n\n";
+ generateCppPackageInclude(out, mPackage, "IHw" + baseName);
+ out << "\n";
enterLeaveNamespace(out, true /* enter */);
out << "\n";
@@ -744,10 +676,11 @@
out << "virtual bool isRemote() const override { return true; }\n\n";
- status_t err = generateMethods(out,
- "" /* class name */,
- MethodLocation::PROXY_HEADER,
- true /* generate specify namespaces */);
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+ method->generateCppSignature(out);
+ out << " override;\n";
+ return OK;
+ });
if (err != OK) {
return err;
@@ -800,33 +733,18 @@
Formatter out(file);
- std::vector<std::string> packageComponents;
- getPackageAndVersionComponents(
- &packageComponents, false /* cpp_compatible */);
-
- std::string prefix;
- for (const auto &component : packageComponents) {
- prefix += component;
- prefix += "/";
- }
-
if (isInterface) {
- out << "#include <" << prefix << "/Bp" << baseName << ".h>\n";
- out << "#include <" << prefix << "/Bn" << baseName << ".h>\n";
- out << "#include <" << prefix << "/Bs" << baseName << ".h>\n";
+ generateCppPackageInclude(out, mPackage, "Bp" + baseName);
+ generateCppPackageInclude(out, mPackage, "Bn" + baseName);
+ generateCppPackageInclude(out, mPackage, "Bs" + baseName);
for (const Interface *superType : iface->superTypeChain()) {
- std::vector<std::string> superPackageComponents;
- superType->fqName().getPackageAndVersionComponents(&superPackageComponents, false /* cpp_compatible */);
- std::string superPrefix;
- for (const auto &component : superPackageComponents) {
- superPrefix += component;
- superPrefix += "/";
- }
- out << "#include <" << superPrefix << "/Bp" << superType->getBaseName() << ".h>\n";
+ generateCppPackageInclude(out,
+ superType->fqName(),
+ "Bp" + superType->getBaseName());
}
} else {
- out << "#include <" << prefix << "types.h>\n";
+ generateCppPackageInclude(out, mPackage, "types");
}
out << "\n";
@@ -868,7 +786,7 @@
out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
<< baseName << ", "
<< "\"" << iface->fqName().package()
- << iface->fqName().version() << "-impl.so\""
+ << iface->fqName().atVersion() << "-impl.so\""
<< ")\n";
}
@@ -959,6 +877,178 @@
}
}
+status_t AST::generateProxyMethodSource(Formatter &out,
+ const std::string &klassName,
+ const Method *method,
+ const Interface *superInterface) const {
+
+ method->generateCppSignature(out,
+ klassName,
+ true /* specify namespaces */);
+
+ const bool returnsValue = !method->results().empty();
+ const TypedVar *elidedReturn = method->canElideCallback();
+
+ out << "{\n";
+
+ out.indent();
+
+ if (returnsValue && elidedReturn == nullptr) {
+ generateCheckNonNull(out, "_hidl_cb");
+ }
+
+ status_t status = generateCppInstrumentationCall(
+ out,
+ InstrumentationEvent::CLIENT_API_ENTRY,
+ method);
+ if (status != OK) {
+ return status;
+ }
+
+ out << "::android::hardware::Parcel _hidl_data;\n";
+ out << "::android::hardware::Parcel _hidl_reply;\n";
+ out << "::android::status_t _hidl_err;\n";
+ out << "::android::hardware::Status _hidl_status;\n\n";
+
+ declareCppReaderLocals(
+ out, method->results(), true /* forResults */);
+
+ out << "_hidl_err = _hidl_data.writeInterfaceToken(";
+ if (!method->isHidlReserved()) {
+ out << superInterface->fqName().cppNamespace()
+ << "::IHw"
+ << superInterface->getBaseName();
+ } else {
+ out << "::android::hardware::IHidlInterfaceBase";
+ }
+ out << "::descriptor);\n";
+
+ 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,
+ "_hidl_data",
+ false /* parcelObjIsPointer */,
+ arg,
+ false /* reader */,
+ Type::ErrorMode_Goto,
+ 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("
+ << method->getSerialId()
+ << " /* "
+ << method->name()
+ << " */, _hidl_data, &_hidl_reply";
+
+ if (method->isOneway()) {
+ out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
+ }
+ out << ");\n";
+
+ out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
+
+ if (!method->isOneway()) {
+ out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
+ 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,
+ "_hidl_reply",
+ false /* parcelObjIsPointer */,
+ arg,
+ true /* reader */,
+ Type::ErrorMode_Goto,
+ 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 << "_hidl_cb(";
+
+ bool first = true;
+ for (const auto &arg : method->results()) {
+ if (!first) {
+ out << ", ";
+ }
+
+ if (arg->type().resultNeedsDeref()) {
+ out << "*";
+ }
+ out << "_hidl_out_" << arg->name();
+
+ first = false;
+ }
+
+ out << ");\n\n";
+ }
+ status_t status = generateCppInstrumentationCall(
+ out,
+ InstrumentationEvent::CLIENT_API_EXIT,
+ method);
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ if (elidedReturn != nullptr) {
+ std::string extra;
+ out << "_hidl_status.setFromStatusT(_hidl_err);\n";
+ out << "return ::android::hardware::Return<";
+ out << elidedReturn->type().getCppResultType(&extra)
+ << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
+ } else {
+ out << "_hidl_status.setFromStatusT(_hidl_err);\n";
+ out << "return ::android::hardware::Return<void>();\n\n";
+ }
+
+ out.unindent();
+ out << "_hidl_error:\n";
+ out.indent();
+ out << "_hidl_status.setFromStatusT(_hidl_err);\n";
+ out << "return ::android::hardware::Return<";
+ if (elidedReturn != nullptr) {
+ std::string extra;
+ out << method->results().at(0)->type().getCppResultType(&extra);
+ } else {
+ out << "void";
+ }
+ out << ">(_hidl_status);\n";
+
+ out.unindent();
+ out << "}\n\n";
+ return OK;
+}
+
status_t AST::generateProxySource(
Formatter &out, const std::string &baseName) const {
const std::string klassName = "Bp" + baseName;
@@ -985,181 +1075,11 @@
out.unindent();
out << "}\n\n";
- const Interface *iface = mRootScope->getInterface();
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
+ return generateProxyMethodSource(out, klassName, method, superInterface);
+ });
- for (const auto &tuple : iface->allMethodsFromRoot()) {
- const Method *method = tuple.method();
- const Interface *superInterface = tuple.interface();
- method->generateCppSignature(out,
- klassName,
- true /* specify namespaces */);
-
- const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
-
- out << "{\n";
-
- out.indent();
-
- if (returnsValue && elidedReturn == nullptr) {
- generateCheckNonNull(out, "_hidl_cb");
- }
-
- status_t status = generateCppInstrumentationCall(
- out,
- InstrumentationEvent::CLIENT_API_ENTRY,
- superInterface,
- method);
- if (status != OK) {
- return status;
- }
-
- out << "::android::hardware::Parcel _hidl_data;\n";
- out << "::android::hardware::Parcel _hidl_reply;\n";
- out << "::android::status_t _hidl_err;\n";
- out << "::android::hardware::Status _hidl_status;\n\n";
-
- declareCppReaderLocals(
- out, method->results(), true /* forResults */);
-
- out << "_hidl_err = _hidl_data.writeInterfaceToken(";
- if (!method->isHidlReserved()) {
- out << superInterface->fqName().cppNamespace()
- << "::IHw"
- << superInterface->getBaseName();
- } else {
- out << "::android::hardware::IHidlInterfaceBase";
- }
- out << "::descriptor);\n";
-
- 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,
- "_hidl_data",
- false /* parcelObjIsPointer */,
- arg,
- false /* reader */,
- Type::ErrorMode_Goto,
- 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("
- << method->getSerialId()
- << " /* "
- << method->name()
- << " */, _hidl_data, &_hidl_reply";
-
- if (method->isOneway()) {
- out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
- }
- out << ");\n";
-
- out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
-
- if (!method->isOneway()) {
- out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
- 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,
- "_hidl_reply",
- false /* parcelObjIsPointer */,
- arg,
- true /* reader */,
- Type::ErrorMode_Goto,
- 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 << "_hidl_cb(";
-
- bool first = true;
- for (const auto &arg : method->results()) {
- if (!first) {
- out << ", ";
- }
-
- if (arg->type().resultNeedsDeref()) {
- out << "*";
- }
- out << "_hidl_out_" << arg->name();
-
- first = false;
- }
-
- out << ");\n\n";
- }
- status_t status = generateCppInstrumentationCall(
- out,
- InstrumentationEvent::CLIENT_API_EXIT,
- superInterface,
- method);
- if (status != OK) {
- return status;
- }
- }
-
- if (elidedReturn != nullptr) {
- std::string extra;
- out << "_hidl_status.setFromStatusT(_hidl_err);\n";
- out << "return ::android::hardware::Return<";
- out << elidedReturn->type().getCppResultType(&extra)
- << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
- } else {
- out << "_hidl_status.setFromStatusT(_hidl_err);\n";
- out << "return ::android::hardware::Return<void>();\n\n";
- }
-
- out.unindent();
- out << "_hidl_error:\n";
- out.indent();
- out << "_hidl_status.setFromStatusT(_hidl_err);\n";
- out << "return ::android::hardware::Return<";
- if (elidedReturn != nullptr) {
- std::string extra;
- out << method->results().at(0)->type().getCppResultType(&extra);
- } else {
- out << "void";
- }
- out << ">(_hidl_status);\n";
-
- out.unindent();
- out << "}\n\n";
- }
-
-
- return OK;
+ return err;
}
status_t AST::generateStubSource(
@@ -1335,7 +1255,6 @@
status_t status = generateCppInstrumentationCall(
out,
InstrumentationEvent::SERVER_API_ENTRY,
- iface,
method);
if (status != OK) {
return status;
@@ -1390,7 +1309,6 @@
status_t status = generateCppInstrumentationCall(
out,
InstrumentationEvent::SERVER_API_EXIT,
- iface,
method);
if (status != OK) {
return status;
@@ -1471,7 +1389,6 @@
status_t status = generateCppInstrumentationCall(
out,
InstrumentationEvent::SERVER_API_EXIT,
- iface,
method);
if (status != OK) {
return status;
@@ -1550,11 +1467,9 @@
&packageComponents, false /* cpp_compatible */);
out << "#include <future>\n";
- out << "#include <";
- for (const auto &component : packageComponents) {
- out << component << "/";
- }
- out << ifaceName << ".h>\n\n";
+
+ generateCppPackageInclude(out, mPackage, ifaceName);
+ out << "\n";
if (supportOneway) {
out << "#include <hidl/TaskRunner.h>\n";
@@ -1566,7 +1481,7 @@
out << "struct "
<< klassName
<< " : " << ifaceName
- << " {\n";
+ << ", HidlInstrumentor {\n";
out.indent();
out << "explicit "
@@ -1575,10 +1490,9 @@
<< ifaceName
<< "> impl);\n";
- status_t err = generateMethods(out,
- "" /* class name */,
- MethodLocation::PASSTHROUGH_HEADER,
- true /* specify namespaces */);
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+ return generatePassthroughMethod(out, method);
+ });
if (err != OK) {
return err;
@@ -1683,7 +1597,9 @@
<< klassName
<< "(const sp<"
<< iface->fullName()
- << "> impl) : mImpl(impl) {";
+ << "> impl) : HidlInstrumentor(\""
+ << iface->fqName().string()
+ << "\"), mImpl(impl) {";
if (iface->hasOnewayMethods()) {
out << "\n";
out.indentBlock([&] {
@@ -1722,7 +1638,7 @@
status_t AST::generateCppInstrumentationCall(
Formatter &out,
InstrumentationEvent event,
- const Interface *iface, const Method *method) const {
+ const Method *method) const {
out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
out.indent();
out << "std::vector<void *> _hidl_args;\n";
@@ -1742,17 +1658,10 @@
case SERVER_API_EXIT:
{
event_str = "InstrumentationEvent::SERVER_API_EXIT";
- const TypedVar *elidedReturn = method->canElideCallback();
- if (elidedReturn != nullptr) {
+ for (const auto &arg : method->results()) {
out << "_hidl_args.push_back((void *)&"
- << elidedReturn->name()
+ << arg->name()
<< ");\n";
- } else {
- for (const auto &arg : method->results()) {
- out << "_hidl_args.push_back((void *)&"
- << arg->name()
- << ");\n";
- }
}
break;
}
@@ -1778,16 +1687,31 @@
}
break;
}
- case SYNC_CALLBACK_ENTRY:
- case SYNC_CALLBACK_EXIT:
- case ASYNC_CALLBACK_ENTRY:
- case ASYNC_CALLBACK_EXIT:
+ case PASSTHROUGH_ENTRY:
{
- LOG(ERROR) << "Not supported instrumentation event: " << event;
+ event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
+ for (const auto &arg : method->args()) {
+ out << "_hidl_args.push_back((void *)&"
+ << arg->name()
+ << ");\n";
+ }
+ break;
+ }
+ case PASSTHROUGH_EXIT:
+ {
+ event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
+ // TODO(b/32576620): passthrough return values
+ break;
+ }
+ default:
+ {
+ LOG(ERROR) << "Unsupported instrumentation event: " << event;
return UNKNOWN_ERROR;
}
}
+ const Interface *iface = mRootScope->getInterface();
+
out << "for (auto callback: mInstrumentationCallbacks) {\n";
out.indent();
out << "callback("
@@ -1795,7 +1719,7 @@
<< ", \""
<< mPackage.package()
<< "\", \""
- << mPackage.getPackageFullVersion()
+ << mPackage.version()
<< "\", \""
<< iface->localName()
<< "\", \""
diff --git a/generateCppImpl.cpp b/generateCppImpl.cpp
index 11ec1d6..25310f5 100644
--- a/generateCppImpl.cpp
+++ b/generateCppImpl.cpp
@@ -48,15 +48,14 @@
status_t AST::generateStubImplMethod(Formatter &out,
const std::string &className,
- const Method *method,
- bool specifyNamespaces) const {
+ const Method *method) const {
// ignore HIDL reserved methods -- implemented in IFoo already.
if (method->isHidlReserved()) {
return OK;
}
- method->generateCppSignature(out, className, specifyNamespaces);
+ method->generateCppSignature(out, className, false /* specifyNamespaces */);
out << " {\n";
@@ -81,24 +80,6 @@
return OK;
}
-status_t AST::generateStubImplDeclaration(Formatter &out,
- const std::string &className,
- const Method *method,
- bool specifyNamespaces) const {
-
- // ignore HIDL reserved methods -- implemented in IFoo already.
- if (method->isHidlReserved()) {
- return OK;
- }
-
- method->generateCppSignature(out,
- className,
- specifyNamespaces);
- out << " override;\n";
-
- return OK;
-}
-
status_t AST::generateStubImplHeader(const std::string &outputPath) const {
std::string ifaceName;
if (!AST::isInterface(&ifaceName)) {
@@ -128,15 +109,7 @@
out << "#ifndef " << guard << "\n";
out << "#define " << guard << "\n\n";
- std::vector<std::string> packageComponents;
- getPackageAndVersionComponents(
- &packageComponents, false /* cpp_compatible */);
-
- out << "#include <";
- for (const auto &component : packageComponents) {
- out << component << "/";
- }
- out << "I" << baseName << ".h>\n";
+ generateCppPackageInclude(out, mPackage, "I" + baseName);
out << "#include <hidl/Status.h>\n\n";
out << "#include <hidl/MQDescriptor.h>\n";
@@ -192,10 +165,16 @@
out.indent();
- status_t err = generateMethods(out,
- "", /* class name */
- MethodLocation::IMPL_HEADER,
- false /* specify namespaces */);
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+ // ignore HIDL reserved methods -- implemented in IFoo already.
+ if (method->isHidlReserved()) {
+ return OK;
+ }
+ method->generateCppSignature(out, "" /* className */,
+ false /* specifyNamespaces */);
+ out << " override;\n";
+ return OK;
+ });
if (err != OK) {
return err;
@@ -250,11 +229,9 @@
// this is namespace aware code and doesn't require post-processing
out.setNamespace("");
- generateMethods(out,
- baseName,
- MethodLocation::IMPL_SOURCE,
- false /* specify namespaces */);
-
+ status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+ return generateStubImplMethod(out, baseName, method);
+ });
out << ifaceName
<< "* ";
diff --git a/generateVts.cpp b/generateVts.cpp
index 35eb0d0..d2e943f 100644
--- a/generateVts.cpp
+++ b/generateVts.cpp
@@ -102,7 +102,7 @@
Formatter out(file);
out << "component_class: HAL_HIDL\n";
- out << "component_type_version: " << mPackage.getPackageFullVersion()
+ out << "component_type_version: " << mPackage.version()
<< "\n";
out << "component_name: \""
<< (isInterface ? ifaceName : "types")
diff --git a/main.cpp b/main.cpp
index d95dadb..1524080 100644
--- a/main.cpp
+++ b/main.cpp
@@ -731,14 +731,14 @@
out.unindent();
out << "],\n";
- out.unindent();
out << "export_shared_lib_headers: [\n";
out.indent();
out << "\"libhidl\",\n"
<< "\"libhwbinder\",\n"
- << "\"libutils\",\n"
- << "],\n";
+ << "\"libutils\",\n";
+ out.unindent();
+ out << "],\n";
out.unindent();
out << "}\n";
diff --git a/test/data/android/hardware/nfc/1.0/NfcClientCallback.vts b/test/data/android/hardware/nfc/1.0/NfcClientCallback.vts
index e2a3e5b..e39ea7c 100644
--- a/test/data/android/hardware/nfc/1.0/NfcClientCallback.vts
+++ b/test/data/android/hardware/nfc/1.0/NfcClientCallback.vts
@@ -11,11 +11,11 @@
name: "sendEvent"
arg: {
type: TYPE_ENUM
- predefined_type: "NfcEvent"
+ predefined_type: "::android::hardware::nfc::V1_0::NfcEvent"
}
arg: {
type: TYPE_ENUM
- predefined_type: "NfcStatus"
+ predefined_type: "::android::hardware::nfc::V1_0::NfcStatus"
}
}
diff --git a/test/data/android/hardware/nfc/1.0/types.vts b/test/data/android/hardware/nfc/1.0/types.vts
index 8e4f93b..e43db1e 100644
--- a/test/data/android/hardware/nfc/1.0/types.vts
+++ b/test/data/android/hardware/nfc/1.0/types.vts
@@ -6,7 +6,7 @@
attribute: {
- name: "NfcEvent"
+ name: "::android::hardware::nfc::V1_0::NfcEvent"
type: TYPE_ENUM
enum_value: {
scalar_type: "uint32_t"
@@ -43,7 +43,7 @@
}
attribute: {
- name: "NfcStatus"
+ name: "::android::hardware::nfc::V1_0::NfcStatus"
type: TYPE_ENUM
enum_value: {
scalar_type: "uint32_t"
diff --git a/test/main.cpp b/test/main.cpp
index 50bada6..8943a9e 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -444,10 +444,11 @@
Abc abcParam{};
abcParam.x = "alphabet";
abcParam.y = 3.14f;
- abcParam.z = new native_handle_t();
+ native_handle_t *handle = native_handle_create(0, 0);
+ abcParam.z = handle;
EXPECT_OK(foo->haveATypeFromAnotherFile(abcParam));
ALOGI("CLIENT haveATypeFromAnotherFile returned.");
- delete abcParam.z;
+ native_handle_delete(handle);
abcParam.z = NULL;
}
@@ -637,10 +638,21 @@
if (gMode == BINDERIZED) {
Abc xyz;
xyz.z = nullptr;
- EXPECT_FAIL(foo->haveATypeFromAnotherFile(xyz));
+ EXPECT_FAIL(bar->expectNullHandle(nullptr, xyz, [](bool hIsNull, bool xyzHasNull) {
+ EXPECT_TRUE(hIsNull);
+ EXPECT_TRUE(xyzHasNull);
+ }));
}
}
+TEST_F(HidlTest, FooNullCallbackTest) {
+ EXPECT_OK(foo->echoNullInterface(nullptr,
+ [](const auto receivedNull, const auto &intf) {
+ EXPECT_TRUE(receivedNull);
+ EXPECT_EQ(intf, nullptr);
+ }));
+}
+
TEST_F(HidlTest, FooNonNullCallbackTest) {
hidl_array<hidl_string, 5, 3> in;