Get method signatures from IBase.hal
instead of hardcoding them in hidl-gen.
Test: hidl_test
Bug: 32559427
Change-Id: Ib0d3beca695fca47eb5f82d5d54c651da9af3687
diff --git a/Interface.cpp b/Interface.cpp
index 01cc063..ad88e31 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -59,30 +59,18 @@
: Scope(localName, location),
mSuperType(super),
mIsJavaCompatibleInProgress(false) {
- mReservedMethods.push_back(createDescriptorChainMethod());
- mReservedMethods.push_back(createGetDescriptorMethod());
- mReservedMethods.push_back(createSyspropsChangedMethod());
- mReservedMethods.push_back(createLinkToDeathMethod());
- mReservedMethods.push_back(createUnlinkToDeathMethod());
- mReservedMethods.push_back(createSetHALInstrumentationMethod());
}
std::string Interface::typeName() const {
return "interface " + localName();
}
-Method *Interface::createLinkToDeathMethod() const {
- auto *results = new std::vector<TypedVar *> {
- new TypedVar("success", new ScalarType(ScalarType::KIND_BOOL)) };
- auto *args = new std::vector<TypedVar *> {
- new TypedVar("recipient", new DeathRecipientType()),
- new TypedVar("cookie", new ScalarType(ScalarType::KIND_UINT64)) };
+bool Interface::fillLinkToDeathMethod(Method *method) const {
+ if (method->name() != "linkToDeath") {
+ return false;
+ }
- return new Method("linkToDeath",
- args,
- results,
- false /*oneway */,
- new std::vector<Annotation *>(),
+ method->fillImplementation(
HIDL_LINK_TO_DEATH_TRANSACTION,
{
{IMPL_HEADER,
@@ -118,19 +106,15 @@
{IMPL_STUB, nullptr}
} /*javaImpl*/
);
+ return true;
}
-Method *Interface::createUnlinkToDeathMethod() const {
- auto *results = new std::vector<TypedVar *> {
- new TypedVar("success", new ScalarType(ScalarType::KIND_BOOL)) };
- auto *args = new std::vector<TypedVar *> {
- new TypedVar("recipient", new DeathRecipientType()) };
+bool Interface::fillUnlinkToDeathMethod(Method *method) const {
+ if (method->name() != "unlinkToDeath") {
+ return false;
+ }
- return new Method("unlinkToDeath",
- args,
- results,
- false /*oneway */,
- new std::vector<Annotation *>(),
+ method->fillImplementation(
HIDL_UNLINK_TO_DEATH_TRANSACTION,
{
{IMPL_HEADER,
@@ -171,13 +155,14 @@
{IMPL_STUB, nullptr /* don't generate code */}
} /*javaImpl*/
);
+ return true;
}
-Method *Interface::createSyspropsChangedMethod() const {
- return new Method("notifySyspropsChanged",
- new std::vector<TypedVar *>() /*args */,
- new std::vector<TypedVar *>() /*results */,
- true /*oneway */,
- new std::vector<Annotation *>(),
+bool Interface::fillSyspropsChangedMethod(Method *method) const {
+ if (method->name() != "notifySyspropsChanged") {
+ return false;
+ }
+
+ method->fillImplementation(
HIDL_SYSPROPS_CHANGED_TRANSACTION,
{ { IMPL_HEADER, [this](auto &out) {
out << "::android::report_sysprop_change();\n";
@@ -187,14 +172,15 @@
out << "android.os.SystemProperties.reportSyspropChanged();";
} } } /*javaImpl */
);
+ return true;
}
-Method *Interface::createSetHALInstrumentationMethod() const {
- return new Method("setHALInstrumentation",
- new std::vector<TypedVar *>() /*args */,
- new std::vector<TypedVar *>() /*results */,
- true /*oneway */,
- new std::vector<Annotation *>(),
+bool Interface::fillSetHALInstrumentationMethod(Method *method) const {
+ if (method->name() != "setHALInstrumentation") {
+ return false;
+ }
+
+ method->fillImplementation(
HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
{
{IMPL_HEADER,
@@ -219,19 +205,15 @@
// Not support for Java Impl for now.
} } } /*javaImpl */
);
+ return true;
}
-Method *Interface::createDescriptorChainMethod() const {
- VectorType *vecType = new VectorType();
- vecType->setElementType(new StringType());
- std::vector<TypedVar *> *results = new std::vector<TypedVar *>();
- results->push_back(new TypedVar("descriptors", vecType));
+bool Interface::fillDescriptorChainMethod(Method *method) const {
+ if (method->name() != "interfaceChain") {
+ return false;
+ }
- return new Method("interfaceChain",
- new std::vector<TypedVar *>() /* args */,
- results,
- false /* oneway */,
- new std::vector<Annotation *>(),
+ method->fillImplementation(
HIDL_DESCRIPTOR_CHAIN_TRANSACTION,
{ { IMPL_HEADER, [this](auto &out) {
std::vector<const Interface *> chain = typeChain();
@@ -255,19 +237,17 @@
}
out << "));";
out.unindent(); out.unindent();
- } } } /* javaImpl */
+ } } } /* javaImpl */
);
+ return true;
}
-Method *Interface::createGetDescriptorMethod() const {
- std::vector<TypedVar *> *results = new std::vector<TypedVar *>();
- results->push_back(new TypedVar("descriptor", new StringType()));
+bool Interface::fillGetDescriptorMethod(Method *method) const {
+ if (method->name() != "interfaceDescriptor") {
+ return false;
+ }
- return new Method("interfaceDescriptor",
- new std::vector<TypedVar *>() /* args */,
- results,
- false /* oneway */,
- new std::vector<Annotation *>(),
+ method->fillImplementation(
HIDL_GET_DESCRIPTOR_TRANSACTION,
{ { IMPL_HEADER, [this](auto &out) {
out << "_hidl_cb("
@@ -279,13 +259,21 @@
out << "return "
<< fullJavaName()
<< ".kInterfaceName;\n";
- } } } /* javaImpl */
+ } } } /* javaImpl */
);
+ return true;
}
+static std::map<std::string, Method *> gAllReservedMethods;
+
bool Interface::addMethod(Method *method) {
if (isIBase()) {
- // ignore addMethod requests for IBase; they are all HIDL reserved methods.
+ if (!gAllReservedMethods.emplace(method->name(), method).second) {
+ LOG(ERROR) << "ERROR: hidl-gen encountered duplicated reserved method "
+ << method->name();
+ return false;
+ }
+ // will add it in addAllReservedMethods
return true;
}
@@ -312,6 +300,35 @@
return true;
}
+bool Interface::addAllReservedMethods() {
+ // use a sorted map to insert them in serial ID order.
+ std::map<int32_t, Method *> reservedMethodsById;
+ for (const auto &pair : gAllReservedMethods) {
+ Method *method = pair.second->copySignature();
+ bool fillSuccess = fillDescriptorChainMethod(method)
+ || fillGetDescriptorMethod(method)
+ || fillSyspropsChangedMethod(method)
+ || fillLinkToDeathMethod(method)
+ || fillUnlinkToDeathMethod(method)
+ || fillSetHALInstrumentationMethod(method);
+ if (!fillSuccess) {
+ LOG(ERROR) << "ERROR: hidl-gen does not recognize a reserved method "
+ << method->name();
+ return false;
+ }
+ if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
+ LOG(ERROR) << "ERROR: hidl-gen uses duplicated serial id for "
+ << method->name() << " and "
+ << reservedMethodsById[method->getSerialId()]->name()
+ << ", serialId = " << method->getSerialId();
+ return false;
+ }
+ }
+ for (const auto &pair : reservedMethodsById) {
+ this->mReservedMethods.push_back(pair.second);
+ }
+ return true;
+}
const Interface *Interface::superType() const {
return mSuperType;
diff --git a/Interface.h b/Interface.h
index 5cba6c4..bcc8748 100644
--- a/Interface.h
+++ b/Interface.h
@@ -30,6 +30,7 @@
Interface(const char *localName, const Location &location, Interface *super);
bool addMethod(Method *method);
+ bool addAllReservedMethods();
bool isElidableType() const override;
bool isInterface() const override;
@@ -113,12 +114,12 @@
std::vector<Method *> mUserMethods;
std::vector<Method *> mReservedMethods;
mutable bool mIsJavaCompatibleInProgress;
- Method *createDescriptorChainMethod() const;
- Method *createGetDescriptorMethod() const;
- Method *createSyspropsChangedMethod() const;
- Method *createLinkToDeathMethod() const;
- Method *createUnlinkToDeathMethod() const;
- Method *createSetHALInstrumentationMethod() const;
+ bool fillDescriptorChainMethod(Method *method) const;
+ bool fillGetDescriptorMethod(Method *method) const;
+ bool fillSyspropsChangedMethod(Method *method) const;
+ bool fillLinkToDeathMethod(Method *method) const;
+ bool fillUnlinkToDeathMethod(Method *method) const;
+ bool fillSetHALInstrumentationMethod(Method *method) const;
DISALLOW_COPY_AND_ASSIGN(Interface);
};
diff --git a/Method.cpp b/Method.cpp
index e41ebd0..38a6c04 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -37,24 +37,16 @@
mAnnotations(annotations) {
}
-// HIDL reserved methods.
-Method::Method(const char *name,
- std::vector<TypedVar *> *args,
- std::vector<TypedVar *> *results,
- bool oneway,
- std::vector<Annotation *> *annotations,
- size_t serial,
- MethodImpl cppImpl,
- MethodImpl javaImpl)
- : Method(name, args, results, oneway, annotations) {
-
+void Method::fillImplementation(
+ size_t serial,
+ MethodImpl cppImpl,
+ MethodImpl javaImpl) {
mIsHidlReserved = true;
mSerial = serial;
mCppImpl = cppImpl;
mJavaImpl = javaImpl;
}
-
std::string Method::name() const {
return mName;
}
@@ -101,6 +93,10 @@
return mJavaImpl.find(type) != mJavaImpl.end();
}
+Method *Method::copySignature() const {
+ return new Method(mName.c_str(), mArgs, mResults, mOneway, mAnnotations);
+}
+
void Method::setSerialId(size_t serial) {
CHECK(!mIsHidlReserved);
mSerial = serial;
diff --git a/Method.h b/Method.h
index 8a05ffc..5a2ad8a 100644
--- a/Method.h
+++ b/Method.h
@@ -50,14 +50,6 @@
std::vector<TypedVar *> *results,
bool oneway,
std::vector<Annotation *> *annotations);
- Method(const char *name,
- std::vector<TypedVar *> *args,
- std::vector<TypedVar *> *results,
- bool oneway,
- std::vector<Annotation *> *annotations,
- size_t serial,
- MethodImpl cppImpl,
- MethodImpl javaImpl);
std::string name() const;
const std::vector<TypedVar *> &args() const;
@@ -70,9 +62,20 @@
bool isHidlReserved() const { return mIsHidlReserved; }
const std::vector<Annotation *> &annotations() const;
+ // Make a copy with the same name, args, results, oneway, annotations.
+ // Implementations, serial are not copied.
+ Method *copySignature() const;
+
void setSerialId(size_t serial);
size_t getSerialId() const;
+ // Fill implementation for HIDL reserved methods. mIsHidlReserved will be
+ // set to true.
+ void fillImplementation(
+ size_t serial,
+ MethodImpl cppImpl,
+ MethodImpl javaImpl);
+
void generateCppSignature(Formatter &out,
const std::string &className = "",
bool specifyNamespaces = true) const;
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 2b33803..9861914 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -637,6 +637,11 @@
}
Interface *iface = static_cast<Interface *>(ast->scope());
+ if (!iface->addAllReservedMethods()) {
+ std::cerr << "ERROR: unknown error in adding reserved methods at "
+ << @5 << "\n";
+ YYERROR;
+ }
ast->leaveScope();