Home | History | Annotate | Download | only in hidl
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "AST.h"
     18 
     19 #include "Coordinator.h"
     20 #include "EnumType.h"
     21 #include "HidlTypeAssertion.h"
     22 #include "Interface.h"
     23 #include "Method.h"
     24 #include "Reference.h"
     25 #include "ScalarType.h"
     26 #include "Scope.h"
     27 
     28 #include <algorithm>
     29 #include <hidl-util/Formatter.h>
     30 #include <hidl-util/StringHelper.h>
     31 #include <android-base/logging.h>
     32 #include <string>
     33 #include <vector>
     34 
     35 namespace android {
     36 
     37 void AST::getPackageComponents(
     38         std::vector<std::string> *components) const {
     39     mPackage.getPackageComponents(components);
     40 }
     41 
     42 void AST::getPackageAndVersionComponents(
     43         std::vector<std::string> *components, bool cpp_compatible) const {
     44     mPackage.getPackageAndVersionComponents(components, cpp_compatible);
     45 }
     46 
     47 std::string AST::makeHeaderGuard(const std::string &baseName,
     48                                  bool indicateGenerated) const {
     49     std::string guard;
     50 
     51     if (indicateGenerated) {
     52         guard += "HIDL_GENERATED_";
     53     }
     54 
     55     guard += StringHelper::Uppercase(mPackage.tokenName());
     56     guard += "_";
     57     guard += StringHelper::Uppercase(baseName);
     58     guard += "_H";
     59 
     60     return guard;
     61 }
     62 
     63 void AST::generateCppPackageInclude(
     64         Formatter &out,
     65         const FQName &package,
     66         const std::string &klass) {
     67 
     68     out << "#include <";
     69 
     70     std::vector<std::string> components;
     71     package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
     72 
     73     for (const auto &component : components) {
     74         out << component << "/";
     75     }
     76 
     77     out << klass
     78         << ".h>\n";
     79 }
     80 
     81 void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
     82     std::vector<std::string> packageComponents;
     83     getPackageAndVersionComponents(
     84             &packageComponents, true /* cpp_compatible */);
     85 
     86     if (enter) {
     87         for (const auto &component : packageComponents) {
     88             out << "namespace " << component << " {\n";
     89         }
     90 
     91         out.setNamespace(mPackage.cppNamespace() + "::");
     92     } else {
     93         out.setNamespace(std::string());
     94 
     95         for (auto it = packageComponents.rbegin();
     96                 it != packageComponents.rend();
     97                 ++it) {
     98             out << "}  // namespace " << *it << "\n";
     99         }
    100     }
    101 }
    102 
    103 static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
    104     const std::string functionName = isTry ? "tryGetService" : "getService";
    105 
    106     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    107         << "const std::string &serviceName=\"default\", bool getStub=false);\n";
    108     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    109         << "const char serviceName[], bool getStub=false)"
    110         << "  { std::string str(serviceName ? serviceName : \"\");"
    111         << "      return " << functionName << "(str, getStub); }\n";
    112     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    113         << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
    114         // without c_str the std::string constructor is ambiguous
    115         << "  { std::string str(serviceName.c_str());"
    116         << "      return " << functionName << "(str, getStub); }\n";
    117     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    118         << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
    119 }
    120 
    121 static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
    122     declareGetService(out, interfaceName, true /* isTry */);
    123     declareGetService(out, interfaceName, false /* isTry */);
    124 
    125     out << "__attribute__ ((warn_unused_result))"
    126         << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
    127     out << "static bool registerForNotifications(\n";
    128     out.indent(2, [&] {
    129         out << "const std::string &serviceName,\n"
    130             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
    131             << "&notification);\n";
    132     });
    133 
    134 }
    135 
    136 static void implementGetService(Formatter &out,
    137         const FQName &fqName,
    138         bool isTry) {
    139 
    140     const std::string interfaceName = fqName.getInterfaceName();
    141     const std::string functionName = isTry ? "tryGetService" : "getService";
    142 
    143     out << "// static\n"
    144         << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
    145         << "const std::string &serviceName, const bool getStub) ";
    146     out.block([&] {
    147         out << "return ::android::hardware::details::getServiceInternal<"
    148             << fqName.getInterfaceProxyName()
    149             << ">(serviceName, "
    150             << (!isTry ? "true" : "false") // retry
    151             << ", getStub);\n";
    152     }).endl().endl();
    153 }
    154 
    155 static void implementServiceManagerInteractions(Formatter &out,
    156         const FQName &fqName, const std::string &package) {
    157 
    158     const std::string interfaceName = fqName.getInterfaceName();
    159 
    160     implementGetService(out, fqName, true /* isTry */);
    161     implementGetService(out, fqName, false /* isTry */);
    162 
    163     out << "::android::status_t " << interfaceName << "::registerAsService("
    164         << "const std::string &serviceName) ";
    165     out.block([&] {
    166         out << "::android::hardware::details::onRegistration(\""
    167             << fqName.getPackageAndVersion().string() << "\", \""
    168             << interfaceName
    169             << "\", serviceName);\n\n";
    170         out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
    171         out.indent(2, [&] {
    172             out << "= ::android::hardware::defaultServiceManager();\n";
    173         });
    174         out.sIf("sm == nullptr", [&] {
    175             out << "return ::android::INVALID_OPERATION;\n";
    176         }).endl();
    177         out << "::android::hardware::Return<bool> ret = "
    178             << "sm->add(serviceName.c_str(), this);\n"
    179             << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
    180     }).endl().endl();
    181 
    182     out << "bool " << interfaceName << "::registerForNotifications(\n";
    183     out.indent(2, [&] {
    184         out << "const std::string &serviceName,\n"
    185             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
    186             << "&notification) ";
    187     });
    188     out.block([&] {
    189         out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
    190         out.indent(2, [&] {
    191             out << "= ::android::hardware::defaultServiceManager();\n";
    192         });
    193         out.sIf("sm == nullptr", [&] {
    194             out << "return false;\n";
    195         }).endl();
    196         out << "::android::hardware::Return<bool> success =\n";
    197         out.indent(2, [&] {
    198             out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
    199             out.indent(2, [&] {
    200                 out << "serviceName, notification);\n";
    201             });
    202         });
    203         out << "return success.isOk() && success;\n";
    204     }).endl().endl();
    205 }
    206 
    207 void AST::generateInterfaceHeader(Formatter& out) const {
    208     const Interface *iface = getInterface();
    209     std::string ifaceName = iface ? iface->localName() : "types";
    210     const std::string guard = makeHeaderGuard(ifaceName);
    211 
    212     out << "#ifndef " << guard << "\n";
    213     out << "#define " << guard << "\n\n";
    214 
    215     for (const auto &item : mImportedNames) {
    216         generateCppPackageInclude(out, item, item.name());
    217     }
    218 
    219     if (!mImportedNames.empty()) {
    220         out << "\n";
    221     }
    222 
    223     if (iface) {
    224         if (isIBase()) {
    225             out << "// skipped #include IServiceNotification.h\n\n";
    226         } else {
    227             out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
    228         }
    229     }
    230 
    231     out << "#include <hidl/HidlSupport.h>\n";
    232     out << "#include <hidl/MQDescriptor.h>\n";
    233 
    234     if (iface) {
    235         out << "#include <hidl/Status.h>\n";
    236     }
    237 
    238     out << "#include <utils/NativeHandle.h>\n";
    239     out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
    240 
    241     enterLeaveNamespace(out, true /* enter */);
    242     out << "\n";
    243 
    244     if (iface) {
    245         out << "struct "
    246             << ifaceName;
    247 
    248         const Interface *superType = iface->superType();
    249 
    250         if (superType == NULL) {
    251             out << " : virtual public ::android::RefBase";
    252         } else {
    253             out << " : public "
    254                 << superType->fullName();
    255         }
    256 
    257         out << " {\n";
    258 
    259         out.indent();
    260 
    261         generateCppTag(out, "android::hardware::details::i_tag");
    262     }
    263 
    264     emitTypeDeclarations(out);
    265 
    266     if (iface) {
    267         out << "virtual bool isRemote() const ";
    268         if (!isIBase()) {
    269             out << "override ";
    270         }
    271         out << "{ return false; }\n\n";
    272 
    273         for (const auto& tuple : iface->allMethodsFromRoot()) {
    274             const Method* method = tuple.method();
    275 
    276             out << "\n";
    277 
    278             const bool returnsValue = !method->results().empty();
    279             const NamedReference<Type>* elidedReturn = method->canElideCallback();
    280 
    281             if (elidedReturn == nullptr && returnsValue) {
    282                 out << "using "
    283                     << method->name()
    284                     << "_cb = std::function<void(";
    285                 method->emitCppResultSignature(out, true /* specify namespaces */);
    286                 out << ")>;\n";
    287             }
    288 
    289             method->dumpAnnotations(out);
    290 
    291             method->emitDocComment(out);
    292 
    293             if (elidedReturn) {
    294                 out << "virtual ::android::hardware::Return<";
    295                 out << elidedReturn->type().getCppResultType() << "> ";
    296             } else {
    297                 out << "virtual ::android::hardware::Return<void> ";
    298             }
    299 
    300             out << method->name()
    301                 << "(";
    302             method->emitCppArgSignature(out, true /* specify namespaces */);
    303             out << ")";
    304             if (method->isHidlReserved()) {
    305                 if (!isIBase()) {
    306                     out << " override";
    307                 }
    308             } else {
    309                 out << " = 0";
    310             }
    311             out << ";\n";
    312         }
    313 
    314         out << "// cast static functions\n";
    315         std::string childTypeResult = iface->getCppResultType();
    316 
    317         for (const Interface *superType : iface->typeChain()) {
    318             out << "static ::android::hardware::Return<"
    319                 << childTypeResult
    320                 << "> castFrom("
    321                 << superType->getCppArgumentType()
    322                 << " parent"
    323                 << ", bool emitError = false);\n";
    324         }
    325 
    326         out << "\nstatic const char* descriptor;\n\n";
    327 
    328         if (isIBase()) {
    329             out << "// skipped getService, registerAsService, registerForNotifications\n\n";
    330         } else {
    331             declareServiceManagerInteractions(out, iface->localName());
    332         }
    333     }
    334 
    335     if (iface) {
    336         out.unindent();
    337 
    338         out << "};\n\n";
    339     }
    340 
    341     mRootScope.emitPackageTypeDeclarations(out);
    342 
    343     out << "\n";
    344     enterLeaveNamespace(out, false /* enter */);
    345 
    346     mRootScope.emitGlobalTypeDeclarations(out);
    347 
    348     out << "\n#endif  // " << guard << "\n";
    349 }
    350 
    351 void AST::generateHwBinderHeader(Formatter& out) const {
    352     const Interface *iface = getInterface();
    353     std::string klassName = iface ? iface->getHwName() : "hwtypes";
    354 
    355     const std::string guard = makeHeaderGuard(klassName);
    356 
    357     out << "#ifndef " << guard << "\n";
    358     out << "#define " << guard << "\n\n";
    359 
    360     generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
    361 
    362     out << "\n";
    363 
    364     for (const auto &item : mImportedNames) {
    365         if (item.name() == "types") {
    366             generateCppPackageInclude(out, item, "hwtypes");
    367         } else {
    368             generateCppPackageInclude(out, item, item.getInterfaceStubName());
    369             generateCppPackageInclude(out, item, item.getInterfaceProxyName());
    370         }
    371     }
    372 
    373     out << "\n";
    374 
    375     out << "#include <hidl/Status.h>\n";
    376     out << "#include <hwbinder/IBinder.h>\n";
    377     out << "#include <hwbinder/Parcel.h>\n";
    378 
    379     out << "\n";
    380 
    381     enterLeaveNamespace(out, true /* enter */);
    382 
    383     mRootScope.emitPackageHwDeclarations(out);
    384 
    385     enterLeaveNamespace(out, false /* enter */);
    386 
    387     out << "\n#endif  // " << guard << "\n";
    388 }
    389 
    390 void AST::emitTypeDeclarations(Formatter& out) const {
    391     return mRootScope.emitTypeDeclarations(out);
    392 }
    393 
    394 static void wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
    395                                bool addPrefixToName, std::function<void(void)> handleError) {
    396     if (!arg->type().isInterface()) {
    397         return;
    398     }
    399     std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
    400     std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
    401             + arg->name();
    402     const Interface &iface = static_cast<const Interface &>(arg->type());
    403     out << iface.getCppStackType() << " " << wrappedName << ";\n";
    404     // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
    405     out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
    406         out << wrappedName
    407             << " = "
    408             << "::android::hardware::details::wrapPassthrough("
    409             << name
    410             << ");\n";
    411         out.sIf(wrappedName + " == nullptr", [&] {
    412             // Fatal error. Happens when the BsFoo class is not found in the binary
    413             // or any dynamic libraries.
    414             handleError();
    415         }).endl();
    416     }).sElse([&] {
    417         out << wrappedName << " = " << name << ";\n";
    418     }).endl().endl();
    419 }
    420 
    421 void AST::generatePassthroughMethod(Formatter& out, const Method* method) const {
    422     method->generateCppSignature(out);
    423 
    424     out << " {\n";
    425     out.indent();
    426 
    427     if (method->isHidlReserved()
    428         && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
    429         method->cppImpl(IMPL_PASSTHROUGH, out);
    430         out.unindent();
    431         out << "}\n\n";
    432         return;
    433     }
    434 
    435     const bool returnsValue = !method->results().empty();
    436     const NamedReference<Type>* elidedReturn = method->canElideCallback();
    437 
    438     if (returnsValue && elidedReturn == nullptr) {
    439         generateCheckNonNull(out, "_hidl_cb");
    440     }
    441 
    442     generateCppInstrumentationCall(
    443             out,
    444             InstrumentationEvent::PASSTHROUGH_ENTRY,
    445             method);
    446 
    447 
    448     for (const auto &arg : method->args()) {
    449         wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
    450             out << "return ::android::hardware::Status::fromExceptionCode(\n";
    451             out.indent(2, [&] {
    452                 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
    453                     << "\"Cannot wrap passthrough interface.\");\n";
    454             });
    455         });
    456     }
    457 
    458     out << "auto _hidl_error = ::android::hardware::Void();\n";
    459     out << "auto _hidl_return = ";
    460 
    461     if (method->isOneway()) {
    462         out << "addOnewayTask([mImpl = this->mImpl\n"
    463             << "#ifdef __ANDROID_DEBUGGABLE__\n"
    464                ", mEnableInstrumentation = this->mEnableInstrumentation, "
    465                "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
    466             << "#endif // __ANDROID_DEBUGGABLE__\n";
    467         for (const auto &arg : method->args()) {
    468             out << ", "
    469                 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
    470                 << arg->name();
    471         }
    472         out << "] {\n";
    473         out.indent();
    474     }
    475 
    476     out << "mImpl->"
    477         << method->name()
    478         << "(";
    479 
    480     out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
    481         out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
    482     });
    483     if (returnsValue && elidedReturn == nullptr) {
    484         // never true if oneway since oneway methods don't return values
    485 
    486         if (!method->args().empty()) {
    487             out << ", ";
    488         }
    489         out << "[&](";
    490         out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
    491             out << "const auto &_hidl_out_"
    492                 << arg->name();
    493         });
    494 
    495         out << ") {\n";
    496         out.indent();
    497         generateCppInstrumentationCall(
    498                 out,
    499                 InstrumentationEvent::PASSTHROUGH_EXIT,
    500                 method);
    501 
    502         for (const auto &arg : method->results()) {
    503             wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
    504                 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
    505                 out.indent(2, [&] {
    506                     out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
    507                         << "\"Cannot wrap passthrough interface.\");\n";
    508                 });
    509                 out << "return;\n";
    510             });
    511         }
    512 
    513         out << "_hidl_cb(";
    514         out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
    515             out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
    516                 << arg->name();
    517         });
    518         out << ");\n";
    519         out.unindent();
    520         out << "});\n\n";
    521     } else {
    522         out << ");\n\n";
    523 
    524         // used by generateCppInstrumentationCall
    525         if (elidedReturn != nullptr) {
    526             out << "#ifdef __ANDROID_DEBUGGABLE__\n"
    527                 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
    528                 << " = _hidl_return;\n"
    529                 << "#endif // __ANDROID_DEBUGGABLE__\n";
    530         }
    531         generateCppInstrumentationCall(
    532                 out,
    533                 InstrumentationEvent::PASSTHROUGH_EXIT,
    534                 method);
    535     }
    536 
    537     if (method->isOneway()) {
    538         out.unindent();
    539         out << "});\n";
    540     }
    541 
    542     out << "return _hidl_return;\n";
    543 
    544     out.unindent();
    545     out << "}\n";
    546 }
    547 
    548 void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
    549     const Interface* iface = mRootScope.getInterface();
    550 
    551     const Interface *prevIterface = nullptr;
    552     for (const auto &tuple : iface->allMethodsFromRoot()) {
    553         const Method *method = tuple.method();
    554         const Interface *superInterface = tuple.interface();
    555 
    556         if (!includeParent && superInterface != iface) {
    557             continue;
    558         }
    559 
    560         if(prevIterface != superInterface) {
    561             if (prevIterface != nullptr) {
    562                 out << "\n";
    563             }
    564             out << "// Methods from "
    565                 << superInterface->fullName()
    566                 << " follow.\n";
    567             prevIterface = superInterface;
    568         }
    569         gen(method, superInterface);
    570     }
    571 
    572     out << "\n";
    573 }
    574 
    575 void AST::generateTemplatizationLink(Formatter& out) const {
    576     out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
    577 }
    578 
    579 void AST::generateCppTag(Formatter& out, const std::string& tag) const {
    580     out << "typedef " << tag << " _hidl_tag;\n\n";
    581 }
    582 
    583 void AST::generateStubHeader(Formatter& out) const {
    584     CHECK(AST::isInterface());
    585 
    586     const Interface* iface = mRootScope.getInterface();
    587     const std::string klassName = iface->getStubName();
    588     const std::string guard = makeHeaderGuard(klassName);
    589 
    590     out << "#ifndef " << guard << "\n";
    591     out << "#define " << guard << "\n\n";
    592 
    593     generateCppPackageInclude(out, mPackage, iface->getHwName());
    594 
    595     out << "\n";
    596 
    597     enterLeaveNamespace(out, true /* enter */);
    598     out << "\n";
    599 
    600     out << "struct "
    601         << klassName;
    602     if (iface->isIBase()) {
    603         out << " : public ::android::hardware::BHwBinder";
    604         out << ", public ::android::hardware::details::HidlInstrumentor {\n";
    605     } else {
    606         out << " : public "
    607             << gIBaseFqName.getInterfaceStubFqName().cppName()
    608             << " {\n";
    609     }
    610 
    611     out.indent();
    612     out << "explicit "
    613         << klassName
    614         << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
    615         << "\n";
    616     out << "explicit "
    617         << klassName
    618         << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
    619         << " const std::string& HidlInstrumentor_package,"
    620         << " const std::string& HidlInstrumentor_interface);"
    621         << "\n\n";
    622     out << "virtual ~" << klassName << "();\n\n";
    623     out << "::android::status_t onTransact(\n";
    624     out.indent();
    625     out.indent();
    626     out << "uint32_t _hidl_code,\n";
    627     out << "const ::android::hardware::Parcel &_hidl_data,\n";
    628     out << "::android::hardware::Parcel *_hidl_reply,\n";
    629     out << "uint32_t _hidl_flags = 0,\n";
    630     out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
    631     out.unindent();
    632     out.unindent();
    633 
    634     out.endl();
    635     generateTemplatizationLink(out);
    636     generateCppTag(out, "android::hardware::details::bnhw_tag");
    637 
    638     out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
    639 
    640     generateMethods(out,
    641                     [&](const Method* method, const Interface*) {
    642                         if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
    643                             return;
    644                         }
    645 
    646                         out << "static ::android::status_t _hidl_" << method->name() << "(\n";
    647 
    648                         out.indent(2,
    649                                    [&] {
    650                                        out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
    651                                            << "const ::android::hardware::Parcel &_hidl_data,\n"
    652                                            << "::android::hardware::Parcel *_hidl_reply,\n"
    653                                            << "TransactCallback _hidl_cb);\n";
    654                                    })
    655                             .endl()
    656                             .endl();
    657                     },
    658                     false /* include parents */);
    659 
    660     out.unindent();
    661     out << "private:\n";
    662     out.indent();
    663 
    664     generateMethods(out, [&](const Method* method, const Interface* iface) {
    665         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
    666             return;
    667         }
    668         const bool returnsValue = !method->results().empty();
    669         const NamedReference<Type>* elidedReturn = method->canElideCallback();
    670 
    671         if (elidedReturn == nullptr && returnsValue) {
    672             out << "using " << method->name() << "_cb = "
    673                 << iface->fqName().cppName()
    674                 << "::" << method->name() << "_cb;\n";
    675         }
    676         method->generateCppSignature(out);
    677         out << ";\n";
    678     });
    679 
    680     out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
    681     out.unindent();
    682     out << "};\n\n";
    683 
    684     enterLeaveNamespace(out, false /* enter */);
    685 
    686     out << "\n#endif  // " << guard << "\n";
    687 }
    688 
    689 void AST::generateProxyHeader(Formatter& out) const {
    690     if (!AST::isInterface()) {
    691         // types.hal does not get a proxy header.
    692         return;
    693     }
    694 
    695     const Interface* iface = mRootScope.getInterface();
    696     const std::string proxyName = iface->getProxyName();
    697     const std::string guard = makeHeaderGuard(proxyName);
    698 
    699     out << "#ifndef " << guard << "\n";
    700     out << "#define " << guard << "\n\n";
    701 
    702     out << "#include <hidl/HidlTransportSupport.h>\n\n";
    703 
    704     std::vector<std::string> packageComponents;
    705     getPackageAndVersionComponents(
    706             &packageComponents, false /* cpp_compatible */);
    707 
    708     generateCppPackageInclude(out, mPackage, iface->getHwName());
    709     out << "\n";
    710 
    711     enterLeaveNamespace(out, true /* enter */);
    712     out << "\n";
    713 
    714     out << "struct "
    715         << proxyName
    716         << " : public ::android::hardware::BpInterface<"
    717         << iface->localName()
    718         << ">, public ::android::hardware::details::HidlInstrumentor {\n";
    719 
    720     out.indent();
    721 
    722     out << "explicit "
    723         << proxyName
    724         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
    725         << "\n\n";
    726 
    727     generateTemplatizationLink(out);
    728     generateCppTag(out, "android::hardware::details::bphw_tag");
    729 
    730     out << "virtual bool isRemote() const override { return true; }\n\n";
    731 
    732     generateMethods(
    733         out,
    734         [&](const Method* method, const Interface*) {
    735             if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
    736                 return;
    737             }
    738 
    739             out << "static ";
    740             method->generateCppReturnType(out);
    741             out << " _hidl_" << method->name() << "("
    742                 << "::android::hardware::IInterface* _hidl_this, "
    743                 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
    744 
    745             if (!method->hasEmptyCppArgSignature()) {
    746                 out << ", ";
    747             }
    748             method->emitCppArgSignature(out);
    749             out << ");\n";
    750         },
    751         false /* include parents */);
    752 
    753     generateMethods(out, [&](const Method* method, const Interface*) {
    754         method->generateCppSignature(out);
    755         out << " override;\n";
    756     });
    757 
    758     out.unindent();
    759     out << "private:\n";
    760     out.indent();
    761     out << "std::mutex _hidl_mMutex;\n"
    762         << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
    763         << " _hidl_mDeathRecipients;\n";
    764     out.unindent();
    765     out << "};\n\n";
    766 
    767     enterLeaveNamespace(out, false /* enter */);
    768 
    769     out << "\n#endif  // " << guard << "\n";
    770 }
    771 
    772 void AST::generateCppSource(Formatter& out) const {
    773     std::string baseName = getBaseName();
    774     const Interface *iface = getInterface();
    775 
    776     const std::string klassName = baseName + (baseName == "types" ? "" : "All");
    777 
    778     out << "#define LOG_TAG \""
    779         << mPackage.string() << "::" << baseName
    780         << "\"\n\n";
    781 
    782     out << "#include <android/log.h>\n";
    783     out << "#include <cutils/trace.h>\n";
    784     out << "#include <hidl/HidlTransportSupport.h>\n\n";
    785     if (iface) {
    786         // This is a no-op for IServiceManager itself.
    787         out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
    788 
    789         generateCppPackageInclude(out, mPackage, iface->getProxyName());
    790         generateCppPackageInclude(out, mPackage, iface->getStubName());
    791         generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
    792 
    793         for (const Interface *superType : iface->superTypeChain()) {
    794             generateCppPackageInclude(out,
    795                                       superType->fqName(),
    796                                       superType->fqName().getInterfaceProxyName());
    797         }
    798 
    799         out << "#include <hidl/ServiceManagement.h>\n";
    800     } else {
    801         generateCppPackageInclude(out, mPackage, "types");
    802         generateCppPackageInclude(out, mPackage, "hwtypes");
    803     }
    804 
    805     out << "\n";
    806 
    807     enterLeaveNamespace(out, true /* enter */);
    808     out << "\n";
    809 
    810     generateTypeSource(out, iface ? iface->localName() : "");
    811 
    812     if (iface) {
    813         const Interface* iface = mRootScope.getInterface();
    814 
    815         // need to be put here, generateStubSource is using this.
    816         out << "const char* "
    817             << iface->localName()
    818             << "::descriptor(\""
    819             << iface->fqName().string()
    820             << "\");\n\n";
    821         out << "__attribute__((constructor)) ";
    822         out << "static void static_constructor() {\n";
    823         out.indent([&] {
    824             out << "::android::hardware::details::getBnConstructorMap().set("
    825                 << iface->localName()
    826                 << "::descriptor,\n";
    827             out.indent(2, [&] {
    828                 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
    829                 out.indent([&] {
    830                     out << "return new "
    831                         << iface->getStubName()
    832                         << "(static_cast<"
    833                         << iface->localName()
    834                         << " *>(iIntf));\n";
    835                 });
    836                 out << "});\n";
    837             });
    838             out << "::android::hardware::details::getBsConstructorMap().set("
    839                 << iface->localName()
    840                 << "::descriptor,\n";
    841             out.indent(2, [&] {
    842                 out << "[](void *iIntf) -> ::android::sp<"
    843                     << gIBaseFqName.cppName()
    844                     << "> {\n";
    845                 out.indent([&] {
    846                     out << "return new "
    847                         << iface->getPassthroughName()
    848                         << "(static_cast<"
    849                         << iface->localName()
    850                         << " *>(iIntf));\n";
    851                 });
    852                 out << "});\n";
    853             });
    854         });
    855         out << "};\n\n";
    856         out << "__attribute__((destructor))";
    857         out << "static void static_destructor() {\n";
    858         out.indent([&] {
    859             out << "::android::hardware::details::getBnConstructorMap().erase("
    860                 << iface->localName()
    861                 << "::descriptor);\n";
    862             out << "::android::hardware::details::getBsConstructorMap().erase("
    863                 << iface->localName()
    864                 << "::descriptor);\n";
    865         });
    866         out << "};\n\n";
    867 
    868         generateInterfaceSource(out);
    869         generateProxySource(out, iface->fqName());
    870         generateStubSource(out, iface);
    871         generatePassthroughSource(out);
    872 
    873         if (isIBase()) {
    874             out << "// skipped getService, registerAsService, registerForNotifications\n";
    875         } else {
    876             std::string package = iface->fqName().package()
    877                     + iface->fqName().atVersion();
    878 
    879             implementServiceManagerInteractions(out, iface->fqName(), package);
    880         }
    881     }
    882 
    883     HidlTypeAssertion::EmitAll(out);
    884     out << "\n";
    885 
    886     enterLeaveNamespace(out, false /* enter */);
    887 }
    888 
    889 void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
    890     out.sIf(nonNull + " == nullptr", [&] {
    891         out << "return ::android::hardware::Status::fromExceptionCode(\n";
    892         out.indent(2, [&] {
    893             out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
    894                 << "\"Null synchronous callback passed.\");\n";
    895         });
    896     }).endl().endl();
    897 }
    898 
    899 void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
    900     mRootScope.emitTypeDefinitions(out, ifaceName);
    901 }
    902 
    903 void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
    904                                  bool forResults) const {
    905     if (args.empty()) {
    906         return;
    907     }
    908 
    909     for (const auto &arg : args) {
    910         const Type &type = arg->type();
    911 
    912         out << type.getCppResultType()
    913             << " "
    914             << (forResults ? "_hidl_out_" : "") + arg->name()
    915             << ";\n";
    916     }
    917 
    918     out << "\n";
    919 }
    920 
    921 void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
    922                               const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
    923                               bool addPrefixToName) const {
    924     const Type &type = arg->type();
    925 
    926     type.emitReaderWriter(
    927             out,
    928             addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
    929             parcelObj,
    930             parcelObjIsPointer,
    931             isReader,
    932             mode);
    933 }
    934 
    935 void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
    936                                    bool parcelObjIsPointer, const NamedReference<Type>* arg,
    937                                    bool isReader, Type::ErrorMode mode,
    938                                    bool addPrefixToName) const {
    939     const Type &type = arg->type();
    940     if(type.needsResolveReferences()) {
    941         type.emitResolveReferences(
    942                 out,
    943                 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
    944                 isReader, // nameIsPointer
    945                 parcelObj,
    946                 parcelObjIsPointer,
    947                 isReader,
    948                 mode);
    949     }
    950 }
    951 
    952 void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
    953                                     const Method* method, const Interface* superInterface) const {
    954     method->generateCppSignature(out,
    955                                  klassName,
    956                                  true /* specify namespaces */);
    957 
    958     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
    959         out.block([&] {
    960             method->cppImpl(IMPL_PROXY, out);
    961         }).endl().endl();
    962         return;
    963     }
    964 
    965     out.block([&] {
    966         const bool returnsValue = !method->results().empty();
    967         const NamedReference<Type>* elidedReturn = method->canElideCallback();
    968 
    969         method->generateCppReturnType(out);
    970 
    971         out << " _hidl_out = "
    972             << superInterface->fqName().cppNamespace()
    973             << "::"
    974             << superInterface->getProxyName()
    975             << "::_hidl_"
    976             << method->name()
    977             << "(this, this";
    978 
    979         if (!method->hasEmptyCppArgSignature()) {
    980             out << ", ";
    981         }
    982 
    983         out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
    984             out << arg->name();
    985         });
    986 
    987         if (returnsValue && elidedReturn == nullptr) {
    988             if (!method->args().empty()) {
    989                 out << ", ";
    990             }
    991             out << "_hidl_cb";
    992         }
    993 
    994         out << ");\n\n";
    995 
    996         out << "return _hidl_out;\n";
    997     }).endl().endl();
    998 }
    999 
   1000 void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
   1001                                           const Method* method) const {
   1002     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
   1003         return;
   1004     }
   1005 
   1006     method->generateCppReturnType(out);
   1007 
   1008     out << klassName
   1009         << "::_hidl_"
   1010         << method->name()
   1011         << "("
   1012         << "::android::hardware::IInterface *_hidl_this, "
   1013         << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
   1014 
   1015     if (!method->hasEmptyCppArgSignature()) {
   1016         out << ", ";
   1017     }
   1018 
   1019     method->emitCppArgSignature(out);
   1020     out << ") {\n";
   1021 
   1022     out.indent();
   1023 
   1024     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   1025     out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
   1026     out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
   1027     out << "#else\n";
   1028     out << "(void) _hidl_this_instrumentor;\n";
   1029     out << "#endif // __ANDROID_DEBUGGABLE__\n";
   1030 
   1031     const bool returnsValue = !method->results().empty();
   1032     const NamedReference<Type>* elidedReturn = method->canElideCallback();
   1033     if (returnsValue && elidedReturn == nullptr) {
   1034         generateCheckNonNull(out, "_hidl_cb");
   1035     }
   1036 
   1037     generateCppInstrumentationCall(
   1038             out,
   1039             InstrumentationEvent::CLIENT_API_ENTRY,
   1040             method);
   1041 
   1042     out << "::android::hardware::Parcel _hidl_data;\n";
   1043     out << "::android::hardware::Parcel _hidl_reply;\n";
   1044     out << "::android::status_t _hidl_err;\n";
   1045     out << "::android::hardware::Status _hidl_status;\n\n";
   1046 
   1047     declareCppReaderLocals(
   1048             out, method->results(), true /* forResults */);
   1049 
   1050     out << "_hidl_err = _hidl_data.writeInterfaceToken(";
   1051     out << klassName;
   1052     out << "::descriptor);\n";
   1053     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1054 
   1055     bool hasInterfaceArgument = false;
   1056     // First DFS: write all buffers and resolve pointers for parent
   1057     for (const auto &arg : method->args()) {
   1058         if (arg->type().isInterface()) {
   1059             hasInterfaceArgument = true;
   1060         }
   1061         emitCppReaderWriter(
   1062                 out,
   1063                 "_hidl_data",
   1064                 false /* parcelObjIsPointer */,
   1065                 arg,
   1066                 false /* reader */,
   1067                 Type::ErrorMode_Goto,
   1068                 false /* addPrefixToName */);
   1069     }
   1070 
   1071     // Second DFS: resolve references.
   1072     for (const auto &arg : method->args()) {
   1073         emitCppResolveReferences(
   1074                 out,
   1075                 "_hidl_data",
   1076                 false /* parcelObjIsPointer */,
   1077                 arg,
   1078                 false /* reader */,
   1079                 Type::ErrorMode_Goto,
   1080                 false /* addPrefixToName */);
   1081     }
   1082 
   1083     if (hasInterfaceArgument) {
   1084         // Start binder threadpool to handle incoming transactions
   1085         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
   1086     }
   1087     out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
   1088         << method->getSerialId()
   1089         << " /* "
   1090         << method->name()
   1091         << " */, _hidl_data, &_hidl_reply";
   1092 
   1093     if (method->isOneway()) {
   1094         out << ", " << Interface::FLAG_ONEWAY << " /* oneway */";
   1095     }
   1096     out << ");\n";
   1097 
   1098     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1099 
   1100     if (!method->isOneway()) {
   1101         out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
   1102         out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1103         out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
   1104 
   1105 
   1106         // First DFS: write all buffers and resolve pointers for parent
   1107         for (const auto &arg : method->results()) {
   1108             emitCppReaderWriter(
   1109                     out,
   1110                     "_hidl_reply",
   1111                     false /* parcelObjIsPointer */,
   1112                     arg,
   1113                     true /* reader */,
   1114                     Type::ErrorMode_Goto,
   1115                     true /* addPrefixToName */);
   1116         }
   1117 
   1118         // Second DFS: resolve references.
   1119         for (const auto &arg : method->results()) {
   1120             emitCppResolveReferences(
   1121                     out,
   1122                     "_hidl_reply",
   1123                     false /* parcelObjIsPointer */,
   1124                     arg,
   1125                     true /* reader */,
   1126                     Type::ErrorMode_Goto,
   1127                     true /* addPrefixToName */);
   1128         }
   1129 
   1130         if (returnsValue && elidedReturn == nullptr) {
   1131             out << "_hidl_cb(";
   1132 
   1133             out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
   1134                 if (arg->type().resultNeedsDeref()) {
   1135                     out << "*";
   1136                 }
   1137                 out << "_hidl_out_" << arg->name();
   1138             });
   1139 
   1140             out << ");\n\n";
   1141         }
   1142     }
   1143 
   1144     generateCppInstrumentationCall(
   1145             out,
   1146             InstrumentationEvent::CLIENT_API_EXIT,
   1147             method);
   1148 
   1149     if (elidedReturn != nullptr) {
   1150         out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1151         out << "return ::android::hardware::Return<";
   1152         out << elidedReturn->type().getCppResultType()
   1153             << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
   1154     } else {
   1155         out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1156         out << "return ::android::hardware::Return<void>();\n\n";
   1157     }
   1158 
   1159     out.unindent();
   1160     out << "_hidl_error:\n";
   1161     out.indent();
   1162     out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1163     out << "return ::android::hardware::Return<";
   1164     if (elidedReturn != nullptr) {
   1165         out << method->results().at(0)->type().getCppResultType();
   1166     } else {
   1167         out << "void";
   1168     }
   1169     out << ">(_hidl_status);\n";
   1170 
   1171     out.unindent();
   1172     out << "}\n\n";
   1173 }
   1174 
   1175 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
   1176     const std::string klassName = fqName.getInterfaceProxyName();
   1177 
   1178     out << klassName
   1179         << "::"
   1180         << klassName
   1181         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
   1182 
   1183     out.indent();
   1184     out.indent();
   1185 
   1186     out << ": BpInterface"
   1187         << "<"
   1188         << fqName.getInterfaceName()
   1189         << ">(_hidl_impl),\n"
   1190         << "  ::android::hardware::details::HidlInstrumentor(\""
   1191         << mPackage.string()
   1192         << "\", \""
   1193         << fqName.getInterfaceName()
   1194         << "\") {\n";
   1195 
   1196     out.unindent();
   1197     out.unindent();
   1198     out << "}\n\n";
   1199 
   1200     generateMethods(out,
   1201                     [&](const Method* method, const Interface*) {
   1202                         generateStaticProxyMethodSource(out, klassName, method);
   1203                     },
   1204                     false /* include parents */);
   1205 
   1206     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
   1207         generateProxyMethodSource(out, klassName, method, superInterface);
   1208     });
   1209 }
   1210 
   1211 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
   1212     const std::string interfaceName = iface->localName();
   1213     const std::string klassName = iface->getStubName();
   1214 
   1215     out << klassName
   1216         << "::"
   1217         << klassName
   1218         << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
   1219 
   1220     out.indent();
   1221     out.indent();
   1222 
   1223     if (iface->isIBase()) {
   1224         out << ": ::android::hardware::details::HidlInstrumentor(\"";
   1225     } else {
   1226         out << ": "
   1227             << gIBaseFqName.getInterfaceStubFqName().cppName()
   1228             << "(_hidl_impl, \"";
   1229     }
   1230 
   1231     out << mPackage.string()
   1232         << "\", \""
   1233         << interfaceName
   1234         << "\") { \n";
   1235     out.indent();
   1236     out << "_hidl_mImpl = _hidl_impl;\n";
   1237     out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
   1238         << "_hidl_impl, {SCHED_NORMAL, 0});\n";
   1239     out << "mSchedPolicy = prio.sched_policy;\n";
   1240     out << "mSchedPriority = prio.prio;\n";
   1241     out.unindent();
   1242 
   1243     out.unindent();
   1244     out.unindent();
   1245     out << "}\n\n";
   1246 
   1247     if (iface->isIBase()) {
   1248         // BnHwBase has a constructor to initialize the HidlInstrumentor
   1249         // class properly.
   1250         out << klassName
   1251             << "::"
   1252             << klassName
   1253             << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
   1254             << " const std::string &HidlInstrumentor_package,"
   1255             << " const std::string &HidlInstrumentor_interface)\n";
   1256 
   1257         out.indent();
   1258         out.indent();
   1259 
   1260         out << ": ::android::hardware::details::HidlInstrumentor("
   1261             << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
   1262         out.indent();
   1263         out << "_hidl_mImpl = _hidl_impl;\n";
   1264         out.unindent();
   1265 
   1266         out.unindent();
   1267         out.unindent();
   1268         out << "}\n\n";
   1269     }
   1270 
   1271     out << klassName << "::~" << klassName << "() ";
   1272     out.block([&]() {
   1273         out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
   1274     }).endl().endl();
   1275 
   1276     generateMethods(out,
   1277                     [&](const Method* method, const Interface*) {
   1278                         return generateStaticStubMethodSource(out, iface->fqName(), method);
   1279                     },
   1280                     false /* include parents */);
   1281 
   1282     generateMethods(out, [&](const Method* method, const Interface*) {
   1283         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
   1284             return;
   1285         }
   1286         method->generateCppSignature(out, iface->getStubName());
   1287         out << " ";
   1288         out.block([&] {
   1289             method->cppImpl(IMPL_STUB_IMPL, out);
   1290         }).endl();
   1291     });
   1292 
   1293     out << "::android::status_t " << klassName << "::onTransact(\n";
   1294 
   1295     out.indent();
   1296     out.indent();
   1297 
   1298     out << "uint32_t _hidl_code,\n"
   1299         << "const ::android::hardware::Parcel &_hidl_data,\n"
   1300         << "::android::hardware::Parcel *_hidl_reply,\n"
   1301         << "uint32_t _hidl_flags,\n"
   1302         << "TransactCallback _hidl_cb) {\n";
   1303 
   1304     out.unindent();
   1305 
   1306     out << "::android::status_t _hidl_err = ::android::OK;\n\n";
   1307     out << "switch (_hidl_code) {\n";
   1308     out.indent();
   1309 
   1310     for (const auto &tuple : iface->allMethodsFromRoot()) {
   1311         const Method *method = tuple.method();
   1312         const Interface *superInterface = tuple.interface();
   1313 
   1314         if (!isIBase() && method->isHidlReserved()) {
   1315             continue;
   1316         }
   1317         out << "case "
   1318             << method->getSerialId()
   1319             << " /* "
   1320             << method->name()
   1321             << " */:\n{\n";
   1322 
   1323         out.indent();
   1324 
   1325         out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONEWAY
   1326             << " /* oneway */;\n";
   1327         out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
   1328         out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
   1329 
   1330         generateStubSourceForMethod(out, method, superInterface);
   1331 
   1332         out.unindent();
   1333         out << "}\n\n";
   1334     }
   1335 
   1336     out << "default:\n{\n";
   1337     out.indent();
   1338 
   1339     if (iface->isIBase()) {
   1340         out << "(void)_hidl_flags;\n";
   1341         out << "return ::android::UNKNOWN_TRANSACTION;\n";
   1342     } else {
   1343         out << "return ";
   1344         out << gIBaseFqName.getInterfaceStubFqName().cppName();
   1345         out << "::onTransact(\n";
   1346 
   1347         out.indent();
   1348         out.indent();
   1349 
   1350         out << "_hidl_code, _hidl_data, _hidl_reply, "
   1351             << "_hidl_flags, _hidl_cb);\n";
   1352 
   1353         out.unindent();
   1354         out.unindent();
   1355     }
   1356 
   1357     out.unindent();
   1358     out << "}\n";
   1359 
   1360     out.unindent();
   1361     out << "}\n\n";
   1362 
   1363     out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
   1364         out << "_hidl_err = ::android::hardware::writeToParcel(\n";
   1365         out.indent(2, [&] {
   1366             out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
   1367             out << "_hidl_reply);\n";
   1368         });
   1369     });
   1370 
   1371     out << "return _hidl_err;\n";
   1372 
   1373     out.unindent();
   1374     out << "}\n\n";
   1375 }
   1376 
   1377 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
   1378                                       const Interface* superInterface) const {
   1379     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
   1380         method->cppImpl(IMPL_STUB, out);
   1381         out << "break;\n";
   1382         return;
   1383     }
   1384 
   1385     out << "_hidl_err = "
   1386         << superInterface->fqName().cppNamespace()
   1387         << "::"
   1388         << superInterface->getStubName()
   1389         << "::_hidl_"
   1390         << method->name()
   1391         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
   1392     out << "break;\n";
   1393 }
   1394 
   1395 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
   1396                                          const Method* method) const {
   1397     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
   1398         return;
   1399     }
   1400 
   1401     const std::string& klassName = fqName.getInterfaceStubName();
   1402 
   1403     out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
   1404 
   1405     out.indent();
   1406     out.indent();
   1407 
   1408     out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
   1409         << "const ::android::hardware::Parcel &_hidl_data,\n"
   1410         << "::android::hardware::Parcel *_hidl_reply,\n"
   1411         << "TransactCallback _hidl_cb) {\n";
   1412 
   1413     out.unindent();
   1414 
   1415     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   1416     out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
   1417     out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
   1418     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
   1419 
   1420     out << "::android::status_t _hidl_err = ::android::OK;\n";
   1421 
   1422     out << "if (!_hidl_data.enforceInterface("
   1423         << klassName
   1424         << "::Pure::descriptor)) {\n";
   1425 
   1426     out.indent();
   1427     out << "_hidl_err = ::android::BAD_TYPE;\n";
   1428     out << "return _hidl_err;\n";
   1429     out.unindent();
   1430     out << "}\n\n";
   1431 
   1432     declareCppReaderLocals(out, method->args(), false /* forResults */);
   1433 
   1434     // First DFS: write buffers
   1435     for (const auto &arg : method->args()) {
   1436         emitCppReaderWriter(
   1437                 out,
   1438                 "_hidl_data",
   1439                 false /* parcelObjIsPointer */,
   1440                 arg,
   1441                 true /* reader */,
   1442                 Type::ErrorMode_Return,
   1443                 false /* addPrefixToName */);
   1444     }
   1445 
   1446     // Second DFS: resolve references
   1447     for (const auto &arg : method->args()) {
   1448         emitCppResolveReferences(
   1449                 out,
   1450                 "_hidl_data",
   1451                 false /* parcelObjIsPointer */,
   1452                 arg,
   1453                 true /* reader */,
   1454                 Type::ErrorMode_Return,
   1455                 false /* addPrefixToName */);
   1456     }
   1457 
   1458     generateCppInstrumentationCall(
   1459             out,
   1460             InstrumentationEvent::SERVER_API_ENTRY,
   1461             method);
   1462 
   1463     const bool returnsValue = !method->results().empty();
   1464     const NamedReference<Type>* elidedReturn = method->canElideCallback();
   1465 
   1466     std::string callee;
   1467 
   1468     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
   1469         callee = "_hidl_this";
   1470     } else {
   1471         callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
   1472     }
   1473 
   1474     if (elidedReturn != nullptr) {
   1475         out << elidedReturn->type().getCppResultType()
   1476             << " _hidl_out_"
   1477             << elidedReturn->name()
   1478             << " = "
   1479             << callee << "->" << method->name()
   1480             << "(";
   1481 
   1482         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
   1483             if (arg->type().resultNeedsDeref()) {
   1484                 out << "*";
   1485             }
   1486             out << arg->name();
   1487         });
   1488 
   1489         out << ");\n\n";
   1490         out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
   1491             << "_hidl_reply);\n\n";
   1492 
   1493         elidedReturn->type().emitReaderWriter(
   1494                 out,
   1495                 "_hidl_out_" + elidedReturn->name(),
   1496                 "_hidl_reply",
   1497                 true, /* parcelObjIsPointer */
   1498                 false, /* isReader */
   1499                 Type::ErrorMode_Ignore);
   1500 
   1501         emitCppResolveReferences(
   1502                 out,
   1503                 "_hidl_reply",
   1504                 true /* parcelObjIsPointer */,
   1505                 elidedReturn,
   1506                 false /* reader */,
   1507                 Type::ErrorMode_Ignore,
   1508                 true /* addPrefixToName */);
   1509 
   1510         generateCppInstrumentationCall(
   1511                 out,
   1512                 InstrumentationEvent::SERVER_API_EXIT,
   1513                 method);
   1514 
   1515         out << "_hidl_cb(*_hidl_reply);\n";
   1516     } else {
   1517         if (returnsValue) {
   1518             out << "bool _hidl_callbackCalled = false;\n\n";
   1519         }
   1520 
   1521         out << callee << "->" << method->name() << "(";
   1522 
   1523         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
   1524             if (arg->type().resultNeedsDeref()) {
   1525                 out << "*";
   1526             }
   1527 
   1528             out << arg->name();
   1529         });
   1530 
   1531         if (returnsValue) {
   1532             if (!method->args().empty()) {
   1533                 out << ", ";
   1534             }
   1535 
   1536             out << "[&](";
   1537 
   1538             out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
   1539                 out << "const auto &_hidl_out_" << arg->name();
   1540             });
   1541 
   1542             out << ") {\n";
   1543             out.indent();
   1544             out << "if (_hidl_callbackCalled) {\n";
   1545             out.indent();
   1546             out << "LOG_ALWAYS_FATAL(\""
   1547                 << method->name()
   1548                 << ": _hidl_cb called a second time, but must be called once.\");\n";
   1549             out.unindent();
   1550             out << "}\n";
   1551             out << "_hidl_callbackCalled = true;\n\n";
   1552 
   1553             out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
   1554                 << "_hidl_reply);\n\n";
   1555 
   1556             // First DFS: buffers
   1557             for (const auto &arg : method->results()) {
   1558                 emitCppReaderWriter(
   1559                         out,
   1560                         "_hidl_reply",
   1561                         true /* parcelObjIsPointer */,
   1562                         arg,
   1563                         false /* reader */,
   1564                         Type::ErrorMode_Ignore,
   1565                         true /* addPrefixToName */);
   1566             }
   1567 
   1568             // Second DFS: resolve references
   1569             for (const auto &arg : method->results()) {
   1570                 emitCppResolveReferences(
   1571                         out,
   1572                         "_hidl_reply",
   1573                         true /* parcelObjIsPointer */,
   1574                         arg,
   1575                         false /* reader */,
   1576                         Type::ErrorMode_Ignore,
   1577                         true /* addPrefixToName */);
   1578             }
   1579 
   1580             generateCppInstrumentationCall(
   1581                     out,
   1582                     InstrumentationEvent::SERVER_API_EXIT,
   1583                     method);
   1584 
   1585             out << "_hidl_cb(*_hidl_reply);\n";
   1586 
   1587             out.unindent();
   1588             out << "});\n\n";
   1589         } else {
   1590             out << ");\n\n";
   1591             out << "(void) _hidl_cb;\n\n";
   1592             generateCppInstrumentationCall(
   1593                     out,
   1594                     InstrumentationEvent::SERVER_API_EXIT,
   1595                     method);
   1596         }
   1597 
   1598         if (returnsValue) {
   1599             out << "if (!_hidl_callbackCalled) {\n";
   1600             out.indent();
   1601             out << "LOG_ALWAYS_FATAL(\""
   1602                 << method->name()
   1603                 << ": _hidl_cb not called, but must be called once.\");\n";
   1604             out.unindent();
   1605             out << "}\n\n";
   1606         } else {
   1607             out << "::android::hardware::writeToParcel("
   1608                 << "::android::hardware::Status::ok(), "
   1609                 << "_hidl_reply);\n\n";
   1610         }
   1611     }
   1612 
   1613     out << "return _hidl_err;\n";
   1614     out.unindent();
   1615     out << "}\n\n";
   1616 }
   1617 
   1618 void AST::generatePassthroughHeader(Formatter& out) const {
   1619     if (!AST::isInterface()) {
   1620         // types.hal does not get a stub header.
   1621         return;
   1622     }
   1623 
   1624     const Interface* iface = mRootScope.getInterface();
   1625     CHECK(iface != nullptr);
   1626 
   1627     const std::string klassName = iface->getPassthroughName();
   1628 
   1629     bool supportOneway = iface->hasOnewayMethods();
   1630 
   1631     const std::string guard = makeHeaderGuard(klassName);
   1632 
   1633     out << "#ifndef " << guard << "\n";
   1634     out << "#define " << guard << "\n\n";
   1635 
   1636     std::vector<std::string> packageComponents;
   1637     getPackageAndVersionComponents(
   1638             &packageComponents, false /* cpp_compatible */);
   1639 
   1640     out << "#include <android-base/macros.h>\n";
   1641     out << "#include <cutils/trace.h>\n";
   1642     out << "#include <future>\n";
   1643 
   1644     generateCppPackageInclude(out, mPackage, iface->localName());
   1645     out << "\n";
   1646 
   1647     out << "#include <hidl/HidlPassthroughSupport.h>\n";
   1648     if (supportOneway) {
   1649         out << "#include <hidl/TaskRunner.h>\n";
   1650     }
   1651 
   1652     enterLeaveNamespace(out, true /* enter */);
   1653     out << "\n";
   1654 
   1655     out << "struct "
   1656         << klassName
   1657         << " : " << iface->localName()
   1658         << ", ::android::hardware::details::HidlInstrumentor {\n";
   1659 
   1660     out.indent();
   1661     out << "explicit "
   1662         << klassName
   1663         << "(const ::android::sp<"
   1664         << iface->localName()
   1665         << "> impl);\n";
   1666 
   1667     out.endl();
   1668     generateTemplatizationLink(out);
   1669     generateCppTag(out, "android::hardware::details::bs_tag");
   1670 
   1671     generateMethods(out, [&](const Method* method, const Interface*) {
   1672         generatePassthroughMethod(out, method);
   1673     });
   1674 
   1675     out.unindent();
   1676     out << "private:\n";
   1677     out.indent();
   1678     out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
   1679 
   1680     if (supportOneway) {
   1681         out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
   1682 
   1683         out << "\n";
   1684 
   1685         out << "::android::hardware::Return<void> addOnewayTask("
   1686                "std::function<void(void)>);\n\n";
   1687     }
   1688 
   1689     out.unindent();
   1690 
   1691     out << "};\n\n";
   1692 
   1693     enterLeaveNamespace(out, false /* enter */);
   1694 
   1695     out << "\n#endif  // " << guard << "\n";
   1696 }
   1697 
   1698 void AST::generateInterfaceSource(Formatter& out) const {
   1699     const Interface* iface = mRootScope.getInterface();
   1700 
   1701     // generate castFrom functions
   1702     std::string childTypeResult = iface->getCppResultType();
   1703 
   1704     generateMethods(out, [&](const Method* method, const Interface*) {
   1705         bool reserved = method->isHidlReserved();
   1706 
   1707         if (!reserved) {
   1708             out << "// no default implementation for: ";
   1709         }
   1710         method->generateCppSignature(out, iface->localName());
   1711         if (reserved) {
   1712             out.block([&]() {
   1713                 method->cppImpl(IMPL_INTERFACE, out);
   1714             }).endl();
   1715         }
   1716 
   1717         out << "\n";
   1718 
   1719         return;
   1720     });
   1721 
   1722     for (const Interface *superType : iface->typeChain()) {
   1723         out << "// static \n::android::hardware::Return<"
   1724             << childTypeResult
   1725             << "> "
   1726             << iface->localName()
   1727             << "::castFrom("
   1728             << superType->getCppArgumentType()
   1729             << " parent, bool "
   1730             << (iface == superType ? "/* emitError */" : "emitError")
   1731             << ") {\n";
   1732         out.indent();
   1733         if (iface == superType) {
   1734             out << "return parent;\n";
   1735         } else {
   1736             out << "return ::android::hardware::details::castInterface<";
   1737             out << iface->localName() << ", "
   1738                 << superType->fqName().cppName() << ", "
   1739                 << iface->getProxyName()
   1740                 << ">(\n";
   1741             out.indent();
   1742             out.indent();
   1743             out << "parent, \""
   1744                 << iface->fqName().string()
   1745                 << "\", emitError);\n";
   1746             out.unindent();
   1747             out.unindent();
   1748         }
   1749         out.unindent();
   1750         out << "}\n\n";
   1751     }
   1752 }
   1753 
   1754 void AST::generatePassthroughSource(Formatter& out) const {
   1755     const Interface* iface = mRootScope.getInterface();
   1756 
   1757     const std::string klassName = iface->getPassthroughName();
   1758 
   1759     out << klassName
   1760         << "::"
   1761         << klassName
   1762         << "(const ::android::sp<"
   1763         << iface->fullName()
   1764         << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
   1765         << mPackage.string()
   1766         << "\", \""
   1767         << iface->localName()
   1768         << "\"), mImpl(impl) {";
   1769     if (iface->hasOnewayMethods()) {
   1770         out << "\n";
   1771         out.indent([&] {
   1772             out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
   1773         });
   1774     }
   1775     out << "}\n\n";
   1776 
   1777     if (iface->hasOnewayMethods()) {
   1778         out << "::android::hardware::Return<void> "
   1779             << klassName
   1780             << "::addOnewayTask(std::function<void(void)> fun) {\n";
   1781         out.indent();
   1782         out << "if (!mOnewayQueue.push(fun)) {\n";
   1783         out.indent();
   1784         out << "return ::android::hardware::Status::fromExceptionCode(\n";
   1785         out.indent();
   1786         out.indent();
   1787         out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
   1788             << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
   1789         out.unindent();
   1790         out.unindent();
   1791         out.unindent();
   1792         out << "}\n";
   1793 
   1794         out << "return ::android::hardware::Status();\n";
   1795 
   1796         out.unindent();
   1797         out << "}\n\n";
   1798 
   1799 
   1800     }
   1801 }
   1802 
   1803 void AST::generateCppAtraceCall(Formatter &out,
   1804                                     InstrumentationEvent event,
   1805                                     const Method *method) const {
   1806     const Interface* iface = mRootScope.getInterface();
   1807     std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
   1808     switch (event) {
   1809         case SERVER_API_ENTRY:
   1810         {
   1811             out << "atrace_begin(ATRACE_TAG_HAL, \""
   1812                 << baseString + "::server\");\n";
   1813             break;
   1814         }
   1815         case CLIENT_API_ENTRY:
   1816         {
   1817             out << "atrace_begin(ATRACE_TAG_HAL, \""
   1818                 << baseString + "::client\");\n";
   1819             break;
   1820         }
   1821         case PASSTHROUGH_ENTRY:
   1822         {
   1823             out << "atrace_begin(ATRACE_TAG_HAL, \""
   1824                 << baseString + "::passthrough\");\n";
   1825             break;
   1826         }
   1827         case SERVER_API_EXIT:
   1828         case CLIENT_API_EXIT:
   1829         case PASSTHROUGH_EXIT:
   1830         {
   1831             out << "atrace_end(ATRACE_TAG_HAL);\n";
   1832             break;
   1833         }
   1834         default:
   1835         {
   1836             CHECK(false) << "Unsupported instrumentation event: " << event;
   1837         }
   1838     }
   1839 }
   1840 
   1841 void AST::generateCppInstrumentationCall(
   1842         Formatter &out,
   1843         InstrumentationEvent event,
   1844         const Method *method) const {
   1845     generateCppAtraceCall(out, event, method);
   1846 
   1847     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   1848     out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
   1849     out.indent();
   1850     out << "std::vector<void *> _hidl_args;\n";
   1851     std::string event_str = "";
   1852     switch (event) {
   1853         case SERVER_API_ENTRY:
   1854         {
   1855             event_str = "InstrumentationEvent::SERVER_API_ENTRY";
   1856             for (const auto &arg : method->args()) {
   1857                 out << "_hidl_args.push_back((void *)"
   1858                     << (arg->type().resultNeedsDeref() ? "" : "&")
   1859                     << arg->name()
   1860                     << ");\n";
   1861             }
   1862             break;
   1863         }
   1864         case SERVER_API_EXIT:
   1865         {
   1866             event_str = "InstrumentationEvent::SERVER_API_EXIT";
   1867             for (const auto &arg : method->results()) {
   1868                 out << "_hidl_args.push_back((void *)&_hidl_out_"
   1869                     << arg->name()
   1870                     << ");\n";
   1871             }
   1872             break;
   1873         }
   1874         case CLIENT_API_ENTRY:
   1875         {
   1876             event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
   1877             for (const auto &arg : method->args()) {
   1878                 out << "_hidl_args.push_back((void *)&"
   1879                     << arg->name()
   1880                     << ");\n";
   1881             }
   1882             break;
   1883         }
   1884         case CLIENT_API_EXIT:
   1885         {
   1886             event_str = "InstrumentationEvent::CLIENT_API_EXIT";
   1887             for (const auto &arg : method->results()) {
   1888                 out << "_hidl_args.push_back((void *)"
   1889                     << (arg->type().resultNeedsDeref() ? "" : "&")
   1890                     << "_hidl_out_"
   1891                     << arg->name()
   1892                     << ");\n";
   1893             }
   1894             break;
   1895         }
   1896         case PASSTHROUGH_ENTRY:
   1897         {
   1898             event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
   1899             for (const auto &arg : method->args()) {
   1900                 out << "_hidl_args.push_back((void *)&"
   1901                     << arg->name()
   1902                     << ");\n";
   1903             }
   1904             break;
   1905         }
   1906         case PASSTHROUGH_EXIT:
   1907         {
   1908             event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
   1909             for (const auto &arg : method->results()) {
   1910                 out << "_hidl_args.push_back((void *)&_hidl_out_"
   1911                     << arg->name()
   1912                     << ");\n";
   1913             }
   1914             break;
   1915         }
   1916         default:
   1917         {
   1918             CHECK(false) << "Unsupported instrumentation event: " << event;
   1919         }
   1920     }
   1921 
   1922     const Interface* iface = mRootScope.getInterface();
   1923 
   1924     out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
   1925     out.indent();
   1926     out << "callback("
   1927         << event_str
   1928         << ", \""
   1929         << mPackage.package()
   1930         << "\", \""
   1931         << mPackage.version()
   1932         << "\", \""
   1933         << iface->localName()
   1934         << "\", \""
   1935         << method->name()
   1936         << "\", &_hidl_args);\n";
   1937     out.unindent();
   1938     out << "}\n";
   1939     out.unindent();
   1940     out << "}\n";
   1941     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
   1942 }
   1943 
   1944 }  // namespace android
   1945