Split 'IFoo' into 'IFoo' and 'IHwFoo'
The traditional binder "IFoo" interface is coupled
very tightly with Binder; it inherits from Binder
objects and implements several Binder-only methods.
We want to abstract away the RPC mechanism as much as we can; therefore,
we want to create a "clean" IFoo interface, which contains just the
methods defined in the HIDL interface. Separately, there's an IHwFoo
interface, which implements IFoo as well as the necessary Binder
methods.
Changes in hidl-gen to support this:
- Generates IHwFoo.h
- Moved (DECLARE|IMPLEMENT)_HW_BINDER macros from IFoo to IHwFoo
- Added REGISTER_AND_GET_SERVICE macros to IFoo
- Removed all hwbinder/ include paths from IFoo
- When passing an interface through a HIDL method, wrap a
BnInterface object around it
- BnFoo's implementation of IFoo calls through the register
interface implementation
- Updated test code
Tests: hidl_test, hidl_java_test, libhwbinder bench, NFC all work.
Bug: 30588200
Change-Id: Ie7ca4eef905f84aebd06bee971b5f6170e169797
diff --git a/Interface.cpp b/Interface.cpp
index f8647a5..fc7e48d 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -56,6 +56,11 @@
return *mAnnotationsByName;
}
+std::string Interface::getBaseName() const {
+ // cut off the leading 'I'.
+ return localName().substr(1);
+}
+
std::string Interface::getCppType(StorageMode mode, std::string *extra) const {
extra->clear();
const std::string base = "::android::sp<" + fullName() + ">";
@@ -103,7 +108,9 @@
out << name
<< " = "
- << fullName()
+ << fqName().cppNamespace()
+ << "::IHw"
+ << getBaseName()
<< "::asInterface("
<< binderName
<< ");\n";
@@ -111,14 +118,33 @@
out.unindent();
out << "}\n\n";
} else {
+
+ out << "if (" << name << "->isRemote()) {\n";
+ out.indent();
out << "_hidl_err = ";
out << parcelObjDeref
<< "writeStrongBinder("
- << fullName()
- << "::asBinder("
- << name
- << "));\n";
-
+ << fqName().cppNamespace()
+ << "::IHw"
+ << getBaseName()
+ << "::asBinder(static_cast<"
+ << fqName().cppNamespace()
+ << "::IHw"
+ << getBaseName()
+ << "*>("
+ << name << ".get()"
+ << ")));\n";
+ out.unindent();
+ out << "} else {\n";
+ out.indent();
+ out << "_hidl_err = ";
+ out << parcelObjDeref
+ << "writeStrongBinder("
+ << "new " << fqName().cppNamespace()
+ << "::Bn" << getBaseName() << " "
+ << "(" << name <<"));\n";
+ out.unindent();
+ out << "}\n";
handleError(out, mode);
}
}