Merge changes Id98050c5,Ib60bb047 am: 08d36d87bc
am: 00dfa0005f
Change-Id: I1fa1e69f8e11fef194aef647742ae62b8c21e688
diff --git a/AST.h b/AST.h
index 9472582..a55cd8c 100644
--- a/AST.h
+++ b/AST.h
@@ -333,8 +333,6 @@
const NamedReference<Type>* arg, bool isReader,
bool addPrefixToName) const;
- void emitTypeDeclarations(Formatter& out) const;
- void emitJavaTypeDeclarations(Formatter& out) const;
void emitVtsTypeDeclarations(Formatter& out) const;
DISALLOW_COPY_AND_ASSIGN(AST);
diff --git a/DocComment.cpp b/DocComment.cpp
index 91bc676..eba3fc0 100644
--- a/DocComment.cpp
+++ b/DocComment.cpp
@@ -16,16 +16,18 @@
#include "DocComment.h"
+#include <android-base/strings.h>
#include <hidl-util/StringHelper.h>
#include <cctype>
#include <sstream>
+#include <iostream>
+
namespace android {
DocComment::DocComment(const std::string& comment) {
- std::vector<std::string> lines;
- StringHelper::SplitString(comment, '\n', &lines);
+ std::vector<std::string> lines = base::Split(base::Trim(comment), "\n");
bool foundFirstLine = false;
@@ -40,17 +42,12 @@
if (idx < line.size() && line[idx] == '*') idx++;
if (idx < line.size() && line[idx] == ' ') idx++;
- if (idx < line.size()) {
- foundFirstLine = true;
- }
+ bool isEmptyLine = idx == line.size();
+ foundFirstLine = foundFirstLine || !isEmptyLine;
if (!foundFirstLine) continue;
- is << line.substr(idx);
-
- if (l + 1 < lines.size()) {
- is << "\n";
- }
+ is << line.substr(idx) << "\n";
}
mComment = is.str();
diff --git a/DocComment.h b/DocComment.h
index e0677eb..b397326 100644
--- a/DocComment.h
+++ b/DocComment.h
@@ -43,7 +43,10 @@
}
}
- private:
+ protected:
+ const DocComment* getDocComment() const { return mDocComment; }
+
+ private:
const DocComment* mDocComment = nullptr;
};
diff --git a/Method.cpp b/Method.cpp
index d81af7c..482bae5 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -149,8 +149,10 @@
return mJavaImpl.find(type) != mJavaImpl.end();
}
-Method *Method::copySignature() const {
- return new Method(mName.c_str(), mArgs, mResults, mOneway, mAnnotations, Location());
+Method* Method::copySignature() const {
+ Method* method = new Method(mName.c_str(), mArgs, mResults, mOneway, mAnnotations, location());
+ method->setDocComment(getDocComment());
+ return method;
}
void Method::setSerialId(size_t serial) {
diff --git a/generateCpp.cpp b/generateCpp.cpp
index affc53d..99ef80a 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -103,17 +103,43 @@
static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
const std::string functionName = isTry ? "tryGetService" : "getService";
+ if (isTry) {
+ DocComment(
+ "This gets the service of this type with the specified instance name. If the\n"
+ "service is currently not available or not in the VINTF manifest on a Trebilized\n"
+ "device, this will return nullptr. This is useful when you don't want to block\n"
+ "during device boot. If getStub is true, this will try to return an unwrapped\n"
+ "passthrough implementation in the same process. This is useful when getting an\n"
+ "implementation from the same partition/compilation group.\n\n"
+ "In general, prefer getService(std::string,bool)")
+ .emit(out);
+ } else {
+ DocComment(
+ "This gets the service of this type with the specified instance name. If the\n"
+ "service is not in the VINTF manifest on a Trebilized device, this will return\n"
+ "nullptr. If the service is not available, this will wait for the service to\n"
+ "become available. If the service is a lazy service, this will start the service\n"
+ "and return when it becomes available. If getStub is true, this will try to\n"
+ "return an unwrapped passthrough implementation in the same process. This is\n"
+ "useful when getting an implementation from the same partition/compilation group.")
+ .emit(out);
+ }
out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
<< "const std::string &serviceName=\"default\", bool getStub=false);\n";
+ DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
<< "const char serviceName[], bool getStub=false)"
<< " { std::string str(serviceName ? serviceName : \"\");"
<< " return " << functionName << "(str, getStub); }\n";
+ DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
<< "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
// without c_str the std::string constructor is ambiguous
<< " { std::string str(serviceName.c_str());"
<< " return " << functionName << "(str, getStub); }\n";
+ DocComment("Calls " + functionName +
+ "(\"default\", bool). This is the recommended instance name for singleton services.")
+ .emit(out);
out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
<< "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
}
@@ -122,8 +148,13 @@
declareGetService(out, interfaceName, true /* isTry */);
declareGetService(out, interfaceName, false /* isTry */);
+ DocComment(
+ "Registers a service with the service manager. For Trebilized devices, the service\n"
+ "must also be in the VINTF manifest.")
+ .emit(out);
out << "__attribute__ ((warn_unused_result))"
<< "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
+ DocComment("Registers for notifications for when a service is registered.").emit(out);
out << "static bool registerForNotifications(\n";
out.indent(2, [&] {
out << "const std::string &serviceName,\n"
@@ -228,6 +259,8 @@
out << "\n";
if (iface) {
+ iface->emitDocComment(out);
+
out << "struct "
<< ifaceName;
@@ -244,17 +277,28 @@
out.indent();
+ DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
+ .emit(out);
generateCppTag(out, "android::hardware::details::i_tag");
+
+ DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
+ .emit(out);
+ out << "static const char* descriptor;\n\n";
+
+ iface->emitTypeDeclarations(out);
+ } else {
+ mRootScope.emitTypeDeclarations(out);
}
- emitTypeDeclarations(out);
-
if (iface) {
+ DocComment(
+ "Returns whether this object's implementation is outside of the current process.")
+ .emit(out);
out << "virtual bool isRemote() const ";
if (!isIBase()) {
out << "override ";
}
- out << "{ return false; }\n\n";
+ out << "{ return false; }\n";
for (const auto& tuple : iface->allMethodsFromRoot()) {
const Method* method = tuple.method();
@@ -265,6 +309,7 @@
const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (elidedReturn == nullptr && returnsValue) {
+ DocComment("Return callback for " + method->name()).emit(out);
out << "using "
<< method->name()
<< "_cb = std::function<void(";
@@ -297,10 +342,14 @@
out << ";\n";
}
- out << "// cast static functions\n";
+ out << "\n// cast static functions\n";
std::string childTypeResult = iface->getCppResultType();
for (const Interface *superType : iface->typeChain()) {
+ DocComment(
+ "This performs a checked cast based on what the underlying implementation "
+ "actually is.")
+ .emit(out);
out << "static ::android::hardware::Return<"
<< childTypeResult
<< "> castFrom("
@@ -309,11 +358,10 @@
<< ", bool emitError = false);\n";
}
- out << "\nstatic const char* descriptor;\n\n";
-
if (isIBase()) {
- out << "// skipped getService, registerAsService, registerForNotifications\n\n";
+ out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
} else {
+ out << "\n// helper methods for interactions with the hwservicemanager\n";
declareServiceManagerInteractions(out, iface->localName());
}
}
@@ -384,10 +432,6 @@
out << "\n#endif // " << guard << "\n";
}
-void AST::emitTypeDeclarations(Formatter& out) const {
- return mRootScope.emitTypeDeclarations(out);
-}
-
static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
std::string name, std::function<void(void)> handleError) {
if (!arg->type().isInterface()) {
@@ -588,6 +632,7 @@
}
void AST::generateTemplatizationLink(Formatter& out) const {
+ DocComment("The pure class is what this class wraps.").emit(out);
out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
}
@@ -648,6 +693,8 @@
out.endl();
generateTemplatizationLink(out);
+ DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
+ .emit(out);
generateCppTag(out, "android::hardware::details::bnhw_tag");
out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
@@ -740,6 +787,8 @@
<< "\n\n";
generateTemplatizationLink(out);
+ DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
+ .emit(out);
generateCppTag(out, "android::hardware::details::bphw_tag");
out << "virtual bool isRemote() const override { return true; }\n\n";
diff --git a/generateJava.cpp b/generateJava.cpp
index 33bd289..b746cc3 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -71,6 +71,19 @@
const std::string& ifaceName,
const std::string& fqName,
bool isRetry) {
+ if (isRetry) {
+ DocComment(
+ "This will invoke the equivalent of the C++ getService(std::string) if retry is\n"
+ "true or tryGetService(std::string) if retry is false. If the service is\n"
+ "available on the device and retry is true, this will wait for the service to\n"
+ "start. Otherwise, it will return immediately even if the service is null.")
+ .emit(out);
+ } else {
+ DocComment(
+ "Warning: this will not wait for the interface to come up if it hasn't yet\n"
+ "started. See getService(String,boolean) instead.")
+ .emit(out);
+ }
out << "public static "
<< ifaceName
<< " getService(String serviceName";
@@ -90,6 +103,14 @@
out << "));\n";
}).endl().endl();
+ if (isRetry) {
+ DocComment("Calls getService(\"default\",retry).").emit(out);
+ } else {
+ DocComment(
+ "Warning: this will not wait for the interface to come up if it hasn't yet "
+ "started. See getService(String,boolean) instead.")
+ .emit(out);
+ }
out << "public static "
<< ifaceName
<< " getService(";
@@ -128,6 +149,8 @@
const Interface *superType = iface->superType();
+ iface->emitDocComment(out);
+
out << "public interface " << ifaceName << " extends ";
if (superType != nullptr) {
@@ -139,12 +162,14 @@
out << " {\n";
out.indent();
+ DocComment("Fully-qualified interface name for this interface.").emit(out);
out << "public static final String kInterfaceName = \""
<< mPackage.string()
<< "::"
<< ifaceName
<< "\";\n\n";
+ DocComment("Does a checked conversion from a binder to this class.").emit(out);
out << "/* package private */ static "
<< ifaceName
<< " asInterface(android.os.IHwBinder binder) {\n";
@@ -196,6 +221,7 @@
out.unindent();
out << "}\n\n";
+ DocComment("Does a checked conversion from any interface to this class.").emit(out);
out << "public static "
<< ifaceName
<< " castFrom(android.os.IHwInterface iface) {\n";
@@ -213,7 +239,7 @@
emitGetService(out, ifaceName, iface->fqName().string(), true /* isRetry */);
emitGetService(out, ifaceName, iface->fqName().string(), false /* isRetry */);
- emitJavaTypeDeclarations(out);
+ iface->emitJavaTypeDeclarations(out, false /* atTopLevel */);
for (const auto &method : iface->methods()) {
const bool returnsValue = !method->results().empty();
@@ -646,8 +672,4 @@
out << "}\n";
}
-void AST::emitJavaTypeDeclarations(Formatter& out) const {
- mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
-}
-
} // namespace android