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 "Interface.h"
     22 #include "HidlTypeAssertion.h"
     23 #include "Method.h"
     24 #include "ScalarType.h"
     25 #include "Scope.h"
     26 
     27 #include <algorithm>
     28 #include <hidl-util/Formatter.h>
     29 #include <hidl-util/StringHelper.h>
     30 #include <android-base/logging.h>
     31 #include <string>
     32 #include <vector>
     33 
     34 namespace android {
     35 
     36 status_t AST::generateCpp(const std::string &outputPath) const {
     37     status_t err = generateCppHeaders(outputPath);
     38 
     39     if (err == OK) {
     40         err = generateCppSources(outputPath);
     41     }
     42 
     43     return err;
     44 }
     45 
     46 status_t AST::generateCppHeaders(const std::string &outputPath) const {
     47     status_t err = generateInterfaceHeader(outputPath);
     48 
     49     if (err == OK) {
     50         err = generateStubHeader(outputPath);
     51     }
     52 
     53     if (err == OK) {
     54         err = generateHwBinderHeader(outputPath);
     55     }
     56 
     57     if (err == OK) {
     58         err = generateProxyHeader(outputPath);
     59     }
     60 
     61     if (err == OK) {
     62         err = generatePassthroughHeader(outputPath);
     63     }
     64 
     65     return err;
     66 }
     67 
     68 void AST::getPackageComponents(
     69         std::vector<std::string> *components) const {
     70     mPackage.getPackageComponents(components);
     71 }
     72 
     73 void AST::getPackageAndVersionComponents(
     74         std::vector<std::string> *components, bool cpp_compatible) const {
     75     mPackage.getPackageAndVersionComponents(components, cpp_compatible);
     76 }
     77 
     78 std::string AST::makeHeaderGuard(const std::string &baseName,
     79                                  bool indicateGenerated) const {
     80     std::string guard;
     81 
     82     if (indicateGenerated) {
     83         guard += "HIDL_GENERATED_";
     84     }
     85 
     86     guard += StringHelper::Uppercase(mPackage.tokenName());
     87     guard += "_";
     88     guard += StringHelper::Uppercase(baseName);
     89     guard += "_H";
     90 
     91     return guard;
     92 }
     93 
     94 void AST::generateCppPackageInclude(
     95         Formatter &out,
     96         const FQName &package,
     97         const std::string &klass) {
     98 
     99     out << "#include <";
    100 
    101     std::vector<std::string> components;
    102     package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
    103 
    104     for (const auto &component : components) {
    105         out << component << "/";
    106     }
    107 
    108     out << klass
    109         << ".h>\n";
    110 }
    111 
    112 void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
    113     std::vector<std::string> packageComponents;
    114     getPackageAndVersionComponents(
    115             &packageComponents, true /* cpp_compatible */);
    116 
    117     if (enter) {
    118         for (const auto &component : packageComponents) {
    119             out << "namespace " << component << " {\n";
    120         }
    121 
    122         out.setNamespace(mPackage.cppNamespace() + "::");
    123     } else {
    124         out.setNamespace(std::string());
    125 
    126         for (auto it = packageComponents.rbegin();
    127                 it != packageComponents.rend();
    128                 ++it) {
    129             out << "}  // namespace " << *it << "\n";
    130         }
    131     }
    132 }
    133 
    134 static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
    135     const std::string functionName = isTry ? "tryGetService" : "getService";
    136 
    137     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    138         << "const std::string &serviceName=\"default\", bool getStub=false);\n";
    139     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    140         << "const char serviceName[], bool getStub=false)"
    141         << "  { std::string str(serviceName ? serviceName : \"\");"
    142         << "      return " << functionName << "(str, getStub); }\n";
    143     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    144         << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
    145         // without c_str the std::string constructor is ambiguous
    146         << "  { std::string str(serviceName.c_str());"
    147         << "      return " << functionName << "(str, getStub); }\n";
    148     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
    149         << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
    150 }
    151 
    152 static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
    153     declareGetService(out, interfaceName, true /* isTry */);
    154     declareGetService(out, interfaceName, false /* isTry */);
    155 
    156     out << "__attribute__ ((warn_unused_result))"
    157         << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
    158     out << "static bool registerForNotifications(\n";
    159     out.indent(2, [&] {
    160         out << "const std::string &serviceName,\n"
    161             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
    162             << "&notification);\n";
    163     });
    164 
    165 }
    166 
    167 static void implementGetService(Formatter &out,
    168         const FQName &fqName,
    169         bool isTry) {
    170 
    171     const std::string interfaceName = fqName.getInterfaceName();
    172     const std::string functionName = isTry ? "tryGetService" : "getService";
    173 
    174     out << "// static\n"
    175         << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
    176         << "const std::string &serviceName, const bool getStub) ";
    177     out.block([&] {
    178         out << "using ::android::hardware::defaultServiceManager;\n";
    179         out << "using ::android::hardware::details::waitForHwService;\n";
    180         out << "using ::android::hardware::getPassthroughServiceManager;\n";
    181         out << "using ::android::hardware::Return;\n";
    182         out << "using ::android::sp;\n";
    183         out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
    184 
    185         out << "sp<" << interfaceName << "> iface = nullptr;\n";
    186 
    187         out.endl();
    188 
    189         out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
    190             << " = defaultServiceManager();\n";
    191 
    192         out.sIf("sm == nullptr", [&] {
    193             // hwbinder is not available on this device, so future tries
    194             // would also be null. I can only return nullptr.
    195             out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
    196                 << "return nullptr;\n";
    197         }).endl().endl();
    198 
    199         out << "Return<Transport> transportRet = sm->getTransport("
    200             << interfaceName << "::descriptor, serviceName);\n\n";
    201 
    202         out.sIf("!transportRet.isOk()", [&] {
    203             out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
    204                 << "transportRet.description().c_str());\n";
    205             out << "return nullptr;\n";
    206         }).endl();
    207 
    208         out << "Transport transport = transportRet;\n";
    209         out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
    210             << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n\n";
    211 
    212         // This means that you must set TREBLE_TESTING_OVERRIDE when running a test such
    213         // as hidl_test. Ideally these binaries set this value themselves. This allows
    214         // test modules to dynamically add and unset services even though they are not
    215         // declared in the device manifest. This prevents a problem where framework
    216         // changes are accidentally made in a way that is not backwards compatible. For
    217         // instance, consider the following situation for two devices developed in the
    218         // same tree:
    219         // A: serves @1.1::IFoo, declares @1.0::IFoo (incorrect)
    220         // B: serves @1.0::IFoo, declares @1.0::IFoo (correct configuration)
    221         // If development is done on device A, then framework code like: "V1_1::IFoo::
    222         // getService()->doV1_0Api()" will work. However, this will unintentionally break
    223         // the feature for devices like device B for which "V1_1::IFoo::getService()
    224         // will return nullptr. In order to prevent problems like this, we only allow
    225         // fetching an interface if it is declared in a VINTF manifest.
    226         out << "#ifdef __ANDROID_TREBLE__\n\n"
    227             << "#ifdef __ANDROID_DEBUGGABLE__\n"
    228             << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
    229             << "const bool trebleTestingOverride =  env && !strcmp(env, \"true\");\n"
    230             << "const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;\n"
    231             << "#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__\n"
    232             << "const bool trebleTestingOverride = false;\n"
    233             << "const bool vintfLegacy = false;\n"
    234             << "#endif // __ANDROID_DEBUGGABLE__\n\n"
    235             << "#else // not __ANDROID_TREBLE__\n"
    236             << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
    237             << "const bool trebleTestingOverride =  env && !strcmp(env, \"true\");\n"
    238             << "const bool vintfLegacy = (transport == Transport::EMPTY);\n\n"
    239             << "#endif // __ANDROID_TREBLE__\n\n";
    240 
    241         // if (getStub) {
    242         //     getPassthroughServiceManager()->get only once.
    243         // } else {
    244         //     if (vintfHwbinder) {
    245         //         while (no alive service) {
    246         //             if (have already tried to get service)
    247         //                 waitForHwService
    248         //             defaultServiceManager()->get
    249         //         }
    250         //     } else if (vintfLegacy) {
    251         //         defaultServiceManager()->get only once.
    252         //         getPassthroughServiceManager()->get only once.
    253         //     } else if (vintfPassthru) {
    254         //         getPassthroughServiceManager()->get only once.
    255         //     }
    256         // }
    257 
    258         out.sFor("int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++", [&] {
    259             if (!isTry) {
    260                 out.sIf("tries > 1", [&] {
    261                     // sleep only after the first time we've called waitForHwService.
    262                     out << "ALOGI(\"" << functionName << ": Will do try %d for %s/%s in 1s...\", tries, "
    263                         << interfaceName << "::descriptor, serviceName.c_str());\n"
    264                         << "sleep(1);\n";
    265                 }).endl();
    266 
    267                 out.sIf("vintfHwbinder && tries > 0", [&] {
    268                     out << "waitForHwService("
    269                         << interfaceName << "::descriptor, serviceName);\n";
    270                 }).endl();
    271             }
    272 
    273             out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
    274             out.indent(2, [&] {
    275                 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
    276             });
    277 
    278             out.sIf("!ret.isOk()", [&] {
    279                 // hwservicemanager fails, may be security issue
    280                 out << "ALOGE(\"" << interfaceName << ": defaultServiceManager()->get returns %s\", "
    281                     << "ret.description().c_str());\n"
    282                     << "break;\n";
    283             }).endl();
    284 
    285             out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
    286             out.sIf("base == nullptr", [&] {
    287                 // if tries > 0: race condition. hwservicemanager drops the service
    288                 // from waitForHwService to here
    289                 out.sIf("tries > 0", [&] {
    290                     out << "ALOGW(\"" << interfaceName << ": found null hwbinder interface\");\n";
    291                 });
    292                 out << (isTry ? "break" : "continue")
    293                     << ";\n";
    294             }).endl();
    295             out << "Return<sp<" << interfaceName
    296                 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
    297             out.sIf("!castRet.isOk()", [&] {
    298                 out.sIf("castRet.isDeadObject()", [&] {
    299                     // service is dead (castFrom cannot call interfaceChain)
    300                     out << "ALOGW(\"" << interfaceName << ": found dead hwbinder service\");\n"
    301                         << (isTry ? "break" : "continue")
    302                         << ";\n";
    303                 }).sElse([&] {
    304                     out << "ALOGW(\"" << interfaceName << ": cannot call into hwbinder service: %s"
    305                         << "; No permission? Check for selinux denials.\", "
    306                         << "castRet.description().c_str());\n"
    307                         << "break;\n";
    308                 }).endl();
    309             }).endl();
    310             out << "iface = castRet;\n";
    311             out.sIf("iface == nullptr", [&] {
    312                 // returned service isn't of correct type; this is a bug
    313                 // to hwservicemanager or to the service itself (interfaceChain
    314                 // is not consistent).
    315                 out << "ALOGW(\"" << interfaceName << ": received incompatible service; bug in hwservicemanager?\");\n"
    316                     << "break;\n";
    317             }).endl();
    318 
    319             out << "return iface;\n";
    320         }).endl();
    321 
    322         out.sIf("getStub || vintfPassthru || vintfLegacy", [&] {
    323             out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
    324                 << " = getPassthroughServiceManager();\n";
    325 
    326             out.sIf("pm != nullptr", [&] () {
    327                 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
    328                 out.indent(2, [&] {
    329                     out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
    330                 });
    331                 out.sIf("ret.isOk()", [&] {
    332                     out << "sp<" << gIBaseFqName.cppName()
    333                         << "> baseInterface = ret;\n";
    334                     out.sIf("baseInterface != nullptr", [&]() {
    335                         out << "iface = " << interfaceName << "::castFrom(baseInterface);\n";
    336                         out.sIf("!getStub || trebleTestingOverride", [&] () {
    337                             out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
    338                         }).endl();
    339                     }).endl();
    340                 }).endl();
    341             }).endl();
    342         }).endl();
    343 
    344         out << "return iface;\n";
    345     }).endl().endl();
    346 }
    347 
    348 static void implementServiceManagerInteractions(Formatter &out,
    349         const FQName &fqName, const std::string &package) {
    350 
    351     const std::string interfaceName = fqName.getInterfaceName();
    352 
    353     implementGetService(out, fqName, true /* isTry */);
    354     implementGetService(out, fqName, false /* isTry */);
    355 
    356     out << "::android::status_t " << interfaceName << "::registerAsService("
    357         << "const std::string &serviceName) ";
    358     out.block([&] {
    359         out << "::android::hardware::details::onRegistration(\""
    360             << fqName.getPackageAndVersion().string() << "\", \""
    361             << interfaceName
    362             << "\", serviceName);\n\n";
    363         out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
    364         out.indent(2, [&] {
    365             out << "= ::android::hardware::defaultServiceManager();\n";
    366         });
    367         out.sIf("sm == nullptr", [&] {
    368             out << "return ::android::INVALID_OPERATION;\n";
    369         }).endl();
    370         out << "::android::hardware::Return<bool> ret = "
    371             << "sm->add(serviceName.c_str(), this);\n"
    372             << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
    373     }).endl().endl();
    374 
    375     out << "bool " << interfaceName << "::registerForNotifications(\n";
    376     out.indent(2, [&] {
    377         out << "const std::string &serviceName,\n"
    378             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
    379             << "&notification) ";
    380     });
    381     out.block([&] {
    382         out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
    383         out.indent(2, [&] {
    384             out << "= ::android::hardware::defaultServiceManager();\n";
    385         });
    386         out.sIf("sm == nullptr", [&] {
    387             out << "return false;\n";
    388         }).endl();
    389         out << "::android::hardware::Return<bool> success =\n";
    390         out.indent(2, [&] {
    391             out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
    392             out.indent(2, [&] {
    393                 out << "serviceName, notification);\n";
    394             });
    395         });
    396         out << "return success.isOk() && success;\n";
    397     }).endl().endl();
    398 }
    399 
    400 status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
    401     const Interface *iface = getInterface();
    402     std::string ifaceName = iface ? iface->localName() : "types";
    403 
    404     std::string path = outputPath;
    405     path.append(mCoordinator->convertPackageRootToPath(mPackage));
    406     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
    407     path.append(ifaceName);
    408     path.append(".h");
    409 
    410     CHECK(Coordinator::MakeParentHierarchy(path));
    411     FILE *file = fopen(path.c_str(), "w");
    412 
    413     if (file == NULL) {
    414         return -errno;
    415     }
    416 
    417     Formatter out(file);
    418 
    419     const std::string guard = makeHeaderGuard(ifaceName);
    420 
    421     out << "#ifndef " << guard << "\n";
    422     out << "#define " << guard << "\n\n";
    423 
    424     for (const auto &item : mImportedNames) {
    425         generateCppPackageInclude(out, item, item.name());
    426     }
    427 
    428     if (!mImportedNames.empty()) {
    429         out << "\n";
    430     }
    431 
    432     if (iface) {
    433         if (isIBase()) {
    434             out << "// skipped #include IServiceNotification.h\n\n";
    435         } else {
    436             out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
    437         }
    438     }
    439 
    440     out << "#include <hidl/HidlSupport.h>\n";
    441     out << "#include <hidl/MQDescriptor.h>\n";
    442 
    443     if (iface) {
    444         out << "#include <hidl/Status.h>\n";
    445     }
    446 
    447     out << "#include <utils/NativeHandle.h>\n";
    448     out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
    449 
    450     enterLeaveNamespace(out, true /* enter */);
    451     out << "\n";
    452 
    453     if (iface) {
    454         out << "struct "
    455             << ifaceName;
    456 
    457         const Interface *superType = iface->superType();
    458 
    459         if (superType == NULL) {
    460             out << " : virtual public ::android::RefBase";
    461         } else {
    462             out << " : public "
    463                 << superType->fullName();
    464         }
    465 
    466         out << " {\n";
    467 
    468         out.indent();
    469 
    470     }
    471 
    472     status_t err = emitTypeDeclarations(out);
    473 
    474     if (err != OK) {
    475         return err;
    476     }
    477 
    478     if (iface) {
    479         out << "virtual bool isRemote() const ";
    480         if (!isIBase()) {
    481             out << "override ";
    482         }
    483         out << "{ return false; }\n\n";
    484 
    485         for (const auto& tuple : iface->allMethodsFromRoot()) {
    486             const Method* method = tuple.method();
    487 
    488             out << "\n";
    489 
    490             const bool returnsValue = !method->results().empty();
    491             const TypedVar *elidedReturn = method->canElideCallback();
    492 
    493             if (elidedReturn == nullptr && returnsValue) {
    494                 out << "using "
    495                     << method->name()
    496                     << "_cb = std::function<void(";
    497                 method->emitCppResultSignature(out, true /* specify namespaces */);
    498                 out << ")>;\n";
    499             }
    500 
    501             method->dumpAnnotations(out);
    502 
    503             if (elidedReturn) {
    504                 out << "virtual ::android::hardware::Return<";
    505                 out << elidedReturn->type().getCppResultType() << "> ";
    506             } else {
    507                 out << "virtual ::android::hardware::Return<void> ";
    508             }
    509 
    510             out << method->name()
    511                 << "(";
    512             method->emitCppArgSignature(out, true /* specify namespaces */);
    513             out << ")";
    514             if (method->isHidlReserved()) {
    515                 if (!isIBase()) {
    516                     out << " override";
    517                 }
    518             } else {
    519                 out << " = 0";
    520             }
    521             out << ";\n";
    522         }
    523 
    524         out << "// cast static functions\n";
    525         std::string childTypeResult = iface->getCppResultType();
    526 
    527         for (const Interface *superType : iface->typeChain()) {
    528             out << "static ::android::hardware::Return<"
    529                 << childTypeResult
    530                 << "> castFrom("
    531                 << superType->getCppArgumentType()
    532                 << " parent"
    533                 << ", bool emitError = false);\n";
    534         }
    535 
    536         out << "\nstatic const char* descriptor;\n\n";
    537 
    538         if (isIBase()) {
    539             out << "// skipped getService, registerAsService, registerForNotifications\n\n";
    540         } else {
    541             declareServiceManagerInteractions(out, iface->localName());
    542         }
    543     }
    544 
    545     if (iface) {
    546         out.unindent();
    547 
    548         out << "};\n\n";
    549     }
    550 
    551     err = mRootScope.emitGlobalTypeDeclarations(out);
    552 
    553     if (err != OK) {
    554         return err;
    555     }
    556 
    557     out << "\n";
    558     enterLeaveNamespace(out, false /* enter */);
    559 
    560     out << "\n#endif  // " << guard << "\n";
    561 
    562     return OK;
    563 }
    564 
    565 status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
    566     const Interface *iface = getInterface();
    567     std::string klassName = iface ? iface->getHwName() : "hwtypes";
    568 
    569     std::string path = outputPath;
    570     path.append(mCoordinator->convertPackageRootToPath(mPackage));
    571     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
    572     path.append(klassName + ".h");
    573 
    574     FILE *file = fopen(path.c_str(), "w");
    575 
    576     if (file == NULL) {
    577         return -errno;
    578     }
    579 
    580     Formatter out(file);
    581 
    582     const std::string guard = makeHeaderGuard(klassName);
    583 
    584     out << "#ifndef " << guard << "\n";
    585     out << "#define " << guard << "\n\n";
    586 
    587     generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
    588 
    589     out << "\n";
    590 
    591     for (const auto &item : mImportedNames) {
    592         if (item.name() == "types") {
    593             generateCppPackageInclude(out, item, "hwtypes");
    594         } else {
    595             generateCppPackageInclude(out, item, item.getInterfaceStubName());
    596             generateCppPackageInclude(out, item, item.getInterfaceProxyName());
    597         }
    598     }
    599 
    600     out << "\n";
    601 
    602     out << "#include <hidl/Status.h>\n";
    603     out << "#include <hwbinder/IBinder.h>\n";
    604     out << "#include <hwbinder/Parcel.h>\n";
    605 
    606     out << "\n";
    607 
    608     enterLeaveNamespace(out, true /* enter */);
    609 
    610     status_t err = mRootScope.emitGlobalHwDeclarations(out);
    611     if (err != OK) {
    612         return err;
    613     }
    614 
    615     enterLeaveNamespace(out, false /* enter */);
    616 
    617     out << "\n#endif  // " << guard << "\n";
    618 
    619     return OK;
    620 }
    621 
    622 status_t AST::emitTypeDeclarations(Formatter &out) const {
    623     return mRootScope.emitTypeDeclarations(out);
    624 }
    625 
    626 static void wrapPassthroughArg(Formatter &out,
    627         const TypedVar *arg, bool addPrefixToName,
    628         std::function<void(void)> handleError) {
    629     if (!arg->type().isInterface()) {
    630         return;
    631     }
    632     std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
    633     std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
    634             + arg->name();
    635     const Interface &iface = static_cast<const Interface &>(arg->type());
    636     out << iface.getCppStackType() << " " << wrappedName << ";\n";
    637     // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
    638     out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
    639         out << wrappedName
    640             << " = "
    641             << iface.fqName().cppName()
    642             << "::castFrom(::android::hardware::details::wrapPassthrough<"
    643             << iface.fqName().cppName()
    644             << ">("
    645             << name << "));\n";
    646         out.sIf(wrappedName + " == nullptr", [&] {
    647             // Fatal error. Happens when the BsFoo class is not found in the binary
    648             // or any dynamic libraries.
    649             handleError();
    650         }).endl();
    651     }).sElse([&] {
    652         out << wrappedName << " = " << name << ";\n";
    653     }).endl().endl();
    654 }
    655 
    656 status_t AST::generatePassthroughMethod(Formatter &out,
    657                                         const Method *method) const {
    658     method->generateCppSignature(out);
    659 
    660     out << " {\n";
    661     out.indent();
    662 
    663     if (method->isHidlReserved()
    664         && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
    665         method->cppImpl(IMPL_PASSTHROUGH, out);
    666         out.unindent();
    667         out << "}\n\n";
    668         return OK;
    669     }
    670 
    671     const bool returnsValue = !method->results().empty();
    672     const TypedVar *elidedReturn = method->canElideCallback();
    673 
    674     if (returnsValue && elidedReturn == nullptr) {
    675         generateCheckNonNull(out, "_hidl_cb");
    676     }
    677 
    678     generateCppInstrumentationCall(
    679             out,
    680             InstrumentationEvent::PASSTHROUGH_ENTRY,
    681             method);
    682 
    683 
    684     for (const auto &arg : method->args()) {
    685         wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
    686             out << "return ::android::hardware::Status::fromExceptionCode(\n";
    687             out.indent(2, [&] {
    688                 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
    689                     << "\"Cannot wrap passthrough interface.\");\n";
    690             });
    691         });
    692     }
    693 
    694     out << "auto _hidl_error = ::android::hardware::Void();\n";
    695     out << "auto _hidl_return = ";
    696 
    697     if (method->isOneway()) {
    698         out << "addOnewayTask([mImpl = this->mImpl\n"
    699             << "#ifdef __ANDROID_DEBUGGABLE__\n"
    700                ", mEnableInstrumentation = this->mEnableInstrumentation, "
    701                "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
    702             << "#endif // __ANDROID_DEBUGGABLE__\n";
    703         for (const auto &arg : method->args()) {
    704             out << ", "
    705                 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
    706                 << arg->name();
    707         }
    708         out << "] {\n";
    709         out.indent();
    710     }
    711 
    712     out << "mImpl->"
    713         << method->name()
    714         << "(";
    715 
    716     out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
    717         out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
    718     });
    719     if (returnsValue && elidedReturn == nullptr) {
    720         // never true if oneway since oneway methods don't return values
    721 
    722         if (!method->args().empty()) {
    723             out << ", ";
    724         }
    725         out << "[&](";
    726         out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
    727             out << "const auto &_hidl_out_"
    728                 << arg->name();
    729         });
    730 
    731         out << ") {\n";
    732         out.indent();
    733         generateCppInstrumentationCall(
    734                 out,
    735                 InstrumentationEvent::PASSTHROUGH_EXIT,
    736                 method);
    737 
    738         for (const auto &arg : method->results()) {
    739             wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
    740                 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
    741                 out.indent(2, [&] {
    742                     out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
    743                         << "\"Cannot wrap passthrough interface.\");\n";
    744                 });
    745                 out << "return;\n";
    746             });
    747         }
    748 
    749         out << "_hidl_cb(";
    750         out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
    751             out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
    752                 << arg->name();
    753         });
    754         out << ");\n";
    755         out.unindent();
    756         out << "});\n\n";
    757     } else {
    758         out << ");\n\n";
    759 
    760         // used by generateCppInstrumentationCall
    761         if (elidedReturn != nullptr) {
    762             out << "#ifdef __ANDROID_DEBUGGABLE__\n"
    763                 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
    764                 << " = _hidl_return;\n"
    765                 << "#endif // __ANDROID_DEBUGGABLE__\n";
    766         }
    767         generateCppInstrumentationCall(
    768                 out,
    769                 InstrumentationEvent::PASSTHROUGH_EXIT,
    770                 method);
    771     }
    772 
    773     if (method->isOneway()) {
    774         out.unindent();
    775         out << "});\n";
    776     }
    777 
    778     out << "return _hidl_return;\n";
    779 
    780     out.unindent();
    781     out << "}\n";
    782 
    783     return OK;
    784 }
    785 
    786 status_t AST::generateMethods(Formatter &out, MethodGenerator gen, bool includeParent) const {
    787     const Interface* iface = mRootScope.getInterface();
    788 
    789     const Interface *prevIterface = nullptr;
    790     for (const auto &tuple : iface->allMethodsFromRoot()) {
    791         const Method *method = tuple.method();
    792         const Interface *superInterface = tuple.interface();
    793 
    794         if (!includeParent && superInterface != iface) {
    795             continue;
    796         }
    797 
    798         if(prevIterface != superInterface) {
    799             if (prevIterface != nullptr) {
    800                 out << "\n";
    801             }
    802             out << "// Methods from "
    803                 << superInterface->fullName()
    804                 << " follow.\n";
    805             prevIterface = superInterface;
    806         }
    807         status_t err = gen(method, superInterface);
    808 
    809         if (err != OK) {
    810             return err;
    811         }
    812     }
    813 
    814     out << "\n";
    815 
    816     return OK;
    817 }
    818 
    819 void AST::generateTemplatizationLink(Formatter& out) const {
    820     out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
    821 }
    822 
    823 status_t AST::generateStubHeader(const std::string &outputPath) const {
    824     if (!AST::isInterface()) {
    825         // types.hal does not get a stub header.
    826         return OK;
    827     }
    828 
    829     const Interface* iface = mRootScope.getInterface();
    830     const std::string klassName = iface->getStubName();
    831 
    832     std::string path = outputPath;
    833     path.append(mCoordinator->convertPackageRootToPath(mPackage));
    834     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
    835     path.append(klassName);
    836     path.append(".h");
    837 
    838     CHECK(Coordinator::MakeParentHierarchy(path));
    839     FILE *file = fopen(path.c_str(), "w");
    840 
    841     if (file == NULL) {
    842         return -errno;
    843     }
    844 
    845     Formatter out(file);
    846 
    847     const std::string guard = makeHeaderGuard(klassName);
    848 
    849     out << "#ifndef " << guard << "\n";
    850     out << "#define " << guard << "\n\n";
    851 
    852     generateCppPackageInclude(out, mPackage, iface->getHwName());
    853     out << "\n";
    854 
    855     enterLeaveNamespace(out, true /* enter */);
    856     out << "\n";
    857 
    858     out << "struct "
    859         << klassName;
    860     if (iface->isIBase()) {
    861         out << " : public ::android::hardware::BHwBinder";
    862         out << ", public ::android::hardware::details::HidlInstrumentor {\n";
    863     } else {
    864         out << " : public "
    865             << gIBaseFqName.getInterfaceStubFqName().cppName()
    866             << " {\n";
    867     }
    868 
    869     out.indent();
    870     out << "explicit "
    871         << klassName
    872         << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
    873         << "\n";
    874     out << "explicit "
    875         << klassName
    876         << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
    877         << " const std::string& HidlInstrumentor_package,"
    878         << " const std::string& HidlInstrumentor_interface);"
    879         << "\n\n";
    880     out << "virtual ~" << klassName << "();\n\n";
    881     out << "::android::status_t onTransact(\n";
    882     out.indent();
    883     out.indent();
    884     out << "uint32_t _hidl_code,\n";
    885     out << "const ::android::hardware::Parcel &_hidl_data,\n";
    886     out << "::android::hardware::Parcel *_hidl_reply,\n";
    887     out << "uint32_t _hidl_flags = 0,\n";
    888     out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
    889     out.unindent();
    890     out.unindent();
    891 
    892     out.endl();
    893     generateTemplatizationLink(out);
    894 
    895     out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; };\n";
    896 
    897     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
    898         if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
    899             return OK;
    900         }
    901 
    902         out << "static ::android::status_t _hidl_" << method->name() << "(\n";
    903 
    904         out.indent(2, [&] {
    905             out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
    906                 << "const ::android::hardware::Parcel &_hidl_data,\n"
    907                 << "::android::hardware::Parcel *_hidl_reply,\n"
    908                 << "TransactCallback _hidl_cb);\n";
    909         }).endl().endl();
    910 
    911         return OK;
    912     }, false /* include parents */);
    913 
    914     if (err != OK) {
    915         return err;
    916     }
    917 
    918     out.unindent();
    919     out << "private:\n";
    920     out.indent();
    921 
    922 
    923     err = generateMethods(out, [&](const Method *method, const Interface *iface) {
    924         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
    925             return OK;
    926         }
    927         const bool returnsValue = !method->results().empty();
    928         const TypedVar *elidedReturn = method->canElideCallback();
    929 
    930         if (elidedReturn == nullptr && returnsValue) {
    931             out << "using " << method->name() << "_cb = "
    932                 << iface->fqName().cppName()
    933                 << "::" << method->name() << "_cb;\n";
    934         }
    935         method->generateCppSignature(out);
    936         out << ";\n";
    937         return OK;
    938     });
    939     if (err != OK) {
    940         return err;
    941     }
    942 
    943     out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
    944     out.unindent();
    945     out << "};\n\n";
    946 
    947     enterLeaveNamespace(out, false /* enter */);
    948 
    949     out << "\n#endif  // " << guard << "\n";
    950 
    951     return OK;
    952 }
    953 
    954 status_t AST::generateProxyHeader(const std::string &outputPath) const {
    955     if (!AST::isInterface()) {
    956         // types.hal does not get a proxy header.
    957         return OK;
    958     }
    959 
    960     const Interface* iface = mRootScope.getInterface();
    961     const std::string proxyName = iface->getProxyName();
    962 
    963     std::string path = outputPath;
    964     path.append(mCoordinator->convertPackageRootToPath(mPackage));
    965     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
    966     path.append(proxyName);
    967     path.append(".h");
    968 
    969     CHECK(Coordinator::MakeParentHierarchy(path));
    970     FILE *file = fopen(path.c_str(), "w");
    971 
    972     if (file == NULL) {
    973         return -errno;
    974     }
    975 
    976     Formatter out(file);
    977 
    978     const std::string guard = makeHeaderGuard(proxyName);
    979 
    980     out << "#ifndef " << guard << "\n";
    981     out << "#define " << guard << "\n\n";
    982 
    983     out << "#include <hidl/HidlTransportSupport.h>\n\n";
    984 
    985     std::vector<std::string> packageComponents;
    986     getPackageAndVersionComponents(
    987             &packageComponents, false /* cpp_compatible */);
    988 
    989     generateCppPackageInclude(out, mPackage, iface->getHwName());
    990     out << "\n";
    991 
    992     enterLeaveNamespace(out, true /* enter */);
    993     out << "\n";
    994 
    995     out << "struct "
    996         << proxyName
    997         << " : public ::android::hardware::BpInterface<"
    998         << iface->localName()
    999         << ">, public ::android::hardware::details::HidlInstrumentor {\n";
   1000 
   1001     out.indent();
   1002 
   1003     out << "explicit "
   1004         << proxyName
   1005         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
   1006         << "\n\n";
   1007 
   1008     generateTemplatizationLink(out);
   1009 
   1010     out << "virtual bool isRemote() const override { return true; }\n\n";
   1011 
   1012     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
   1013         if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
   1014             return OK;
   1015         }
   1016 
   1017         out << "static ";
   1018         method->generateCppReturnType(out);
   1019         out << " _hidl_"
   1020             << method->name()
   1021             << "("
   1022             << "::android::hardware::IInterface* _hidl_this, "
   1023             << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
   1024 
   1025         if (!method->hasEmptyCppArgSignature()) {
   1026             out << ", ";
   1027         }
   1028         method->emitCppArgSignature(out);
   1029         out << ");\n";
   1030         return OK;
   1031     }, false /* include parents */);
   1032 
   1033     if (err != OK) {
   1034         return err;
   1035     }
   1036 
   1037     err = generateMethods(out, [&](const Method *method, const Interface *) {
   1038         method->generateCppSignature(out);
   1039         out << " override;\n";
   1040         return OK;
   1041     });
   1042 
   1043     if (err != OK) {
   1044         return err;
   1045     }
   1046 
   1047     out.unindent();
   1048     out << "private:\n";
   1049     out.indent();
   1050     out << "std::mutex _hidl_mMutex;\n"
   1051         << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
   1052         << " _hidl_mDeathRecipients;\n";
   1053     out.unindent();
   1054     out << "};\n\n";
   1055 
   1056     enterLeaveNamespace(out, false /* enter */);
   1057 
   1058     out << "\n#endif  // " << guard << "\n";
   1059 
   1060     return OK;
   1061 }
   1062 
   1063 status_t AST::generateCppSources(const std::string &outputPath) const {
   1064     std::string baseName = getBaseName();
   1065     const Interface *iface = getInterface();
   1066 
   1067     std::string path = outputPath;
   1068     path.append(mCoordinator->convertPackageRootToPath(mPackage));
   1069     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
   1070     path.append(baseName);
   1071 
   1072     if (baseName != "types") {
   1073         path.append("All");
   1074     }
   1075 
   1076     path.append(".cpp");
   1077 
   1078     CHECK(Coordinator::MakeParentHierarchy(path));
   1079     FILE *file = fopen(path.c_str(), "w");
   1080 
   1081     if (file == NULL) {
   1082         return -errno;
   1083     }
   1084 
   1085     Formatter out(file);
   1086 
   1087     out << "#define LOG_TAG \""
   1088         << mPackage.string() << "::" << baseName
   1089         << "\"\n\n";
   1090 
   1091     out << "#include <android/log.h>\n";
   1092     out << "#include <cutils/trace.h>\n";
   1093     out << "#include <hidl/HidlTransportSupport.h>\n\n";
   1094     if (iface) {
   1095         // This is a no-op for IServiceManager itself.
   1096         out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
   1097 
   1098         generateCppPackageInclude(out, mPackage, iface->getProxyName());
   1099         generateCppPackageInclude(out, mPackage, iface->getStubName());
   1100         generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
   1101 
   1102         for (const Interface *superType : iface->superTypeChain()) {
   1103             generateCppPackageInclude(out,
   1104                                       superType->fqName(),
   1105                                       superType->fqName().getInterfaceProxyName());
   1106         }
   1107 
   1108         out << "#include <hidl/ServiceManagement.h>\n";
   1109     } else {
   1110         generateCppPackageInclude(out, mPackage, "types");
   1111         generateCppPackageInclude(out, mPackage, "hwtypes");
   1112     }
   1113 
   1114     out << "\n";
   1115 
   1116     enterLeaveNamespace(out, true /* enter */);
   1117     out << "\n";
   1118 
   1119     status_t err = generateTypeSource(out, iface ? iface->localName() : "");
   1120 
   1121     if (err == OK && iface) {
   1122         const Interface* iface = mRootScope.getInterface();
   1123 
   1124         // need to be put here, generateStubSource is using this.
   1125         out << "const char* "
   1126             << iface->localName()
   1127             << "::descriptor(\""
   1128             << iface->fqName().string()
   1129             << "\");\n\n";
   1130         out << "__attribute__((constructor))";
   1131         out << "static void static_constructor() {\n";
   1132         out.indent([&] {
   1133             out << "::android::hardware::details::gBnConstructorMap.set("
   1134                 << iface->localName()
   1135                 << "::descriptor,\n";
   1136             out.indent(2, [&] {
   1137                 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
   1138                 out.indent([&] {
   1139                     out << "return new "
   1140                         << iface->getStubName()
   1141                         << "(static_cast<"
   1142                         << iface->localName()
   1143                         << " *>(iIntf));\n";
   1144                 });
   1145                 out << "});\n";
   1146             });
   1147             out << "::android::hardware::details::gBsConstructorMap.set("
   1148                 << iface->localName()
   1149                 << "::descriptor,\n";
   1150             out.indent(2, [&] {
   1151                 out << "[](void *iIntf) -> ::android::sp<"
   1152                     << gIBaseFqName.cppName()
   1153                     << "> {\n";
   1154                 out.indent([&] {
   1155                     out << "return new "
   1156                         << iface->getPassthroughName()
   1157                         << "(static_cast<"
   1158                         << iface->localName()
   1159                         << " *>(iIntf));\n";
   1160                 });
   1161                 out << "});\n";
   1162             });
   1163         });
   1164         out << "};\n\n";
   1165         out << "__attribute__((destructor))";
   1166         out << "static void static_destructor() {\n";
   1167         out.indent([&] {
   1168             out << "::android::hardware::details::gBnConstructorMap.erase("
   1169                 << iface->localName()
   1170                 << "::descriptor);\n";
   1171             out << "::android::hardware::details::gBsConstructorMap.erase("
   1172                 << iface->localName()
   1173                 << "::descriptor);\n";
   1174         });
   1175         out << "};\n\n";
   1176 
   1177         err = generateInterfaceSource(out);
   1178     }
   1179 
   1180     if (err == OK && iface) {
   1181         err = generateProxySource(out, iface->fqName());
   1182     }
   1183 
   1184     if (err == OK && iface) {
   1185         err = generateStubSource(out, iface);
   1186     }
   1187 
   1188     if (err == OK && iface) {
   1189         err = generatePassthroughSource(out);
   1190     }
   1191 
   1192     if (err == OK && iface) {
   1193         const Interface* iface = mRootScope.getInterface();
   1194 
   1195         if (isIBase()) {
   1196             out << "// skipped getService, registerAsService, registerForNotifications\n";
   1197         } else {
   1198             std::string package = iface->fqName().package()
   1199                     + iface->fqName().atVersion();
   1200 
   1201             implementServiceManagerInteractions(out, iface->fqName(), package);
   1202         }
   1203     }
   1204 
   1205     HidlTypeAssertion::EmitAll(out);
   1206     out << "\n";
   1207 
   1208     enterLeaveNamespace(out, false /* enter */);
   1209 
   1210     return err;
   1211 }
   1212 
   1213 void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
   1214     out.sIf(nonNull + " == nullptr", [&] {
   1215         out << "return ::android::hardware::Status::fromExceptionCode(\n";
   1216         out.indent(2, [&] {
   1217             out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
   1218                 << "\"Null synchronous callback passed.\");\n";
   1219         });
   1220     }).endl().endl();
   1221 }
   1222 
   1223 status_t AST::generateTypeSource(
   1224         Formatter &out, const std::string &ifaceName) const {
   1225     return mRootScope.emitTypeDefinitions(out, ifaceName);
   1226 }
   1227 
   1228 void AST::declareCppReaderLocals(
   1229         Formatter &out,
   1230         const std::vector<TypedVar *> &args,
   1231         bool forResults) const {
   1232     if (args.empty()) {
   1233         return;
   1234     }
   1235 
   1236     for (const auto &arg : args) {
   1237         const Type &type = arg->type();
   1238 
   1239         out << type.getCppResultType()
   1240             << " "
   1241             << (forResults ? "_hidl_out_" : "") + arg->name()
   1242             << ";\n";
   1243     }
   1244 
   1245     out << "\n";
   1246 }
   1247 
   1248 void AST::emitCppReaderWriter(
   1249         Formatter &out,
   1250         const std::string &parcelObj,
   1251         bool parcelObjIsPointer,
   1252         const TypedVar *arg,
   1253         bool isReader,
   1254         Type::ErrorMode mode,
   1255         bool addPrefixToName) const {
   1256     const Type &type = arg->type();
   1257 
   1258     type.emitReaderWriter(
   1259             out,
   1260             addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
   1261             parcelObj,
   1262             parcelObjIsPointer,
   1263             isReader,
   1264             mode);
   1265 }
   1266 
   1267 void AST::emitCppResolveReferences(
   1268         Formatter &out,
   1269         const std::string &parcelObj,
   1270         bool parcelObjIsPointer,
   1271         const TypedVar *arg,
   1272         bool isReader,
   1273         Type::ErrorMode mode,
   1274         bool addPrefixToName) const {
   1275     const Type &type = arg->type();
   1276     if(type.needsResolveReferences()) {
   1277         type.emitResolveReferences(
   1278                 out,
   1279                 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
   1280                 isReader, // nameIsPointer
   1281                 parcelObj,
   1282                 parcelObjIsPointer,
   1283                 isReader,
   1284                 mode);
   1285     }
   1286 }
   1287 
   1288 status_t AST::generateProxyMethodSource(Formatter &out,
   1289                                         const std::string &klassName,
   1290                                         const Method *method,
   1291                                         const Interface *superInterface) const {
   1292     method->generateCppSignature(out,
   1293                                  klassName,
   1294                                  true /* specify namespaces */);
   1295 
   1296     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
   1297         out.block([&] {
   1298             method->cppImpl(IMPL_PROXY, out);
   1299         }).endl().endl();
   1300         return OK;
   1301     }
   1302 
   1303     status_t err = OK;
   1304 
   1305     out.block([&] {
   1306         const bool returnsValue = !method->results().empty();
   1307         const TypedVar *elidedReturn = method->canElideCallback();
   1308 
   1309         method->generateCppReturnType(out);
   1310 
   1311         out << " _hidl_out = "
   1312             << superInterface->fqName().cppNamespace()
   1313             << "::"
   1314             << superInterface->getProxyName()
   1315             << "::_hidl_"
   1316             << method->name()
   1317             << "(this, this";
   1318 
   1319         if (!method->hasEmptyCppArgSignature()) {
   1320             out << ", ";
   1321         }
   1322 
   1323         out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
   1324             out << arg->name();
   1325         });
   1326 
   1327         if (returnsValue && elidedReturn == nullptr) {
   1328             if (!method->args().empty()) {
   1329                 out << ", ";
   1330             }
   1331             out << "_hidl_cb";
   1332         }
   1333 
   1334         out << ");\n\n";
   1335 
   1336         out << "return _hidl_out;\n";
   1337     }).endl().endl();
   1338 
   1339     return err;
   1340 }
   1341 
   1342 status_t AST::generateStaticProxyMethodSource(Formatter &out,
   1343                                               const std::string &klassName,
   1344                                               const Method *method) const {
   1345     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
   1346         return OK;
   1347     }
   1348 
   1349     method->generateCppReturnType(out);
   1350 
   1351     out << klassName
   1352         << "::_hidl_"
   1353         << method->name()
   1354         << "("
   1355         << "::android::hardware::IInterface *_hidl_this, "
   1356         << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
   1357 
   1358     if (!method->hasEmptyCppArgSignature()) {
   1359         out << ", ";
   1360     }
   1361 
   1362     method->emitCppArgSignature(out);
   1363     out << ") {\n";
   1364 
   1365     out.indent();
   1366 
   1367     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   1368     out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
   1369     out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
   1370     out << "#else\n";
   1371     out << "(void) _hidl_this_instrumentor;\n";
   1372     out << "#endif // __ANDROID_DEBUGGABLE__\n";
   1373 
   1374     const bool returnsValue = !method->results().empty();
   1375     const TypedVar *elidedReturn = method->canElideCallback();
   1376     if (returnsValue && elidedReturn == nullptr) {
   1377         generateCheckNonNull(out, "_hidl_cb");
   1378     }
   1379 
   1380     generateCppInstrumentationCall(
   1381             out,
   1382             InstrumentationEvent::CLIENT_API_ENTRY,
   1383             method);
   1384 
   1385     out << "::android::hardware::Parcel _hidl_data;\n";
   1386     out << "::android::hardware::Parcel _hidl_reply;\n";
   1387     out << "::android::status_t _hidl_err;\n";
   1388     out << "::android::hardware::Status _hidl_status;\n\n";
   1389 
   1390     declareCppReaderLocals(
   1391             out, method->results(), true /* forResults */);
   1392 
   1393     out << "_hidl_err = _hidl_data.writeInterfaceToken(";
   1394     out << klassName;
   1395     out << "::descriptor);\n";
   1396     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1397 
   1398     bool hasInterfaceArgument = false;
   1399     // First DFS: write all buffers and resolve pointers for parent
   1400     for (const auto &arg : method->args()) {
   1401         if (arg->type().isInterface()) {
   1402             hasInterfaceArgument = true;
   1403         }
   1404         emitCppReaderWriter(
   1405                 out,
   1406                 "_hidl_data",
   1407                 false /* parcelObjIsPointer */,
   1408                 arg,
   1409                 false /* reader */,
   1410                 Type::ErrorMode_Goto,
   1411                 false /* addPrefixToName */);
   1412     }
   1413 
   1414     // Second DFS: resolve references.
   1415     for (const auto &arg : method->args()) {
   1416         emitCppResolveReferences(
   1417                 out,
   1418                 "_hidl_data",
   1419                 false /* parcelObjIsPointer */,
   1420                 arg,
   1421                 false /* reader */,
   1422                 Type::ErrorMode_Goto,
   1423                 false /* addPrefixToName */);
   1424     }
   1425 
   1426     if (hasInterfaceArgument) {
   1427         // Start binder threadpool to handle incoming transactions
   1428         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
   1429     }
   1430     out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
   1431         << method->getSerialId()
   1432         << " /* "
   1433         << method->name()
   1434         << " */, _hidl_data, &_hidl_reply";
   1435 
   1436     if (method->isOneway()) {
   1437         out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
   1438     }
   1439     out << ");\n";
   1440 
   1441     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1442 
   1443     if (!method->isOneway()) {
   1444         out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
   1445         out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
   1446         out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
   1447 
   1448 
   1449         // First DFS: write all buffers and resolve pointers for parent
   1450         for (const auto &arg : method->results()) {
   1451             emitCppReaderWriter(
   1452                     out,
   1453                     "_hidl_reply",
   1454                     false /* parcelObjIsPointer */,
   1455                     arg,
   1456                     true /* reader */,
   1457                     Type::ErrorMode_Goto,
   1458                     true /* addPrefixToName */);
   1459         }
   1460 
   1461         // Second DFS: resolve references.
   1462         for (const auto &arg : method->results()) {
   1463             emitCppResolveReferences(
   1464                     out,
   1465                     "_hidl_reply",
   1466                     false /* parcelObjIsPointer */,
   1467                     arg,
   1468                     true /* reader */,
   1469                     Type::ErrorMode_Goto,
   1470                     true /* addPrefixToName */);
   1471         }
   1472 
   1473         if (returnsValue && elidedReturn == nullptr) {
   1474             out << "_hidl_cb(";
   1475 
   1476             out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
   1477                 if (arg->type().resultNeedsDeref()) {
   1478                     out << "*";
   1479                 }
   1480                 out << "_hidl_out_" << arg->name();
   1481             });
   1482 
   1483             out << ");\n\n";
   1484         }
   1485     }
   1486 
   1487     generateCppInstrumentationCall(
   1488             out,
   1489             InstrumentationEvent::CLIENT_API_EXIT,
   1490             method);
   1491 
   1492     if (elidedReturn != nullptr) {
   1493         out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1494         out << "return ::android::hardware::Return<";
   1495         out << elidedReturn->type().getCppResultType()
   1496             << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
   1497     } else {
   1498         out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1499         out << "return ::android::hardware::Return<void>();\n\n";
   1500     }
   1501 
   1502     out.unindent();
   1503     out << "_hidl_error:\n";
   1504     out.indent();
   1505     out << "_hidl_status.setFromStatusT(_hidl_err);\n";
   1506     out << "return ::android::hardware::Return<";
   1507     if (elidedReturn != nullptr) {
   1508         out << method->results().at(0)->type().getCppResultType();
   1509     } else {
   1510         out << "void";
   1511     }
   1512     out << ">(_hidl_status);\n";
   1513 
   1514     out.unindent();
   1515     out << "}\n\n";
   1516     return OK;
   1517 }
   1518 
   1519 status_t AST::generateProxySource(
   1520         Formatter &out, const FQName &fqName) const {
   1521     const std::string klassName = fqName.getInterfaceProxyName();
   1522 
   1523     out << klassName
   1524         << "::"
   1525         << klassName
   1526         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
   1527 
   1528     out.indent();
   1529     out.indent();
   1530 
   1531     out << ": BpInterface"
   1532         << "<"
   1533         << fqName.getInterfaceName()
   1534         << ">(_hidl_impl),\n"
   1535         << "  ::android::hardware::details::HidlInstrumentor(\""
   1536         << mPackage.string()
   1537         << "\", \""
   1538         << fqName.getInterfaceName()
   1539         << "\") {\n";
   1540 
   1541     out.unindent();
   1542     out.unindent();
   1543     out << "}\n\n";
   1544 
   1545     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
   1546         return generateStaticProxyMethodSource(out, klassName, method);
   1547     }, false /* include parents */);
   1548 
   1549     if (err != OK) {
   1550         return err;
   1551     }
   1552 
   1553     err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
   1554         return generateProxyMethodSource(out, klassName, method, superInterface);
   1555     });
   1556 
   1557     return err;
   1558 }
   1559 
   1560 status_t AST::generateStubSource(
   1561         Formatter &out,
   1562         const Interface *iface) const {
   1563     const std::string interfaceName = iface->localName();
   1564     const std::string klassName = iface->getStubName();
   1565 
   1566     out << klassName
   1567         << "::"
   1568         << klassName
   1569         << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
   1570 
   1571     out.indent();
   1572     out.indent();
   1573 
   1574     if (iface->isIBase()) {
   1575         out << ": ::android::hardware::details::HidlInstrumentor(\"";
   1576     } else {
   1577         out << ": "
   1578             << gIBaseFqName.getInterfaceStubFqName().cppName()
   1579             << "(_hidl_impl, \"";
   1580     }
   1581 
   1582     out << mPackage.string()
   1583         << "\", \""
   1584         << interfaceName
   1585         << "\") { \n";
   1586     out.indent();
   1587     out << "_hidl_mImpl = _hidl_impl;\n";
   1588     out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
   1589         << "_hidl_impl, {SCHED_NORMAL, 0});\n";
   1590     out << "mSchedPolicy = prio.sched_policy;\n";
   1591     out << "mSchedPriority = prio.prio;\n";
   1592     out.unindent();
   1593 
   1594     out.unindent();
   1595     out.unindent();
   1596     out << "}\n\n";
   1597 
   1598     if (iface->isIBase()) {
   1599         // BnHwBase has a constructor to initialize the HidlInstrumentor
   1600         // class properly.
   1601         out << klassName
   1602             << "::"
   1603             << klassName
   1604             << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
   1605             << " const std::string &HidlInstrumentor_package,"
   1606             << " const std::string &HidlInstrumentor_interface)\n";
   1607 
   1608         out.indent();
   1609         out.indent();
   1610 
   1611         out << ": ::android::hardware::details::HidlInstrumentor("
   1612             << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
   1613         out.indent();
   1614         out << "_hidl_mImpl = _hidl_impl;\n";
   1615         out.unindent();
   1616 
   1617         out.unindent();
   1618         out.unindent();
   1619         out << "}\n\n";
   1620     }
   1621 
   1622     out << klassName << "::~" << klassName << "() ";
   1623     out.block([&]() {
   1624         out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
   1625     }).endl().endl();
   1626 
   1627     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
   1628         return generateStaticStubMethodSource(out, klassName, method);
   1629     }, false /* include parents */);
   1630 
   1631     err = generateMethods(out, [&](const Method *method, const Interface *) {
   1632         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
   1633             return OK;
   1634         }
   1635         method->generateCppSignature(out, iface->getStubName());
   1636         out << " ";
   1637         out.block([&] {
   1638             method->cppImpl(IMPL_STUB_IMPL, out);
   1639         }).endl();
   1640         return OK;
   1641     });
   1642     if (err != OK) {
   1643         return err;
   1644     }
   1645 
   1646     out << "::android::status_t " << klassName << "::onTransact(\n";
   1647 
   1648     out.indent();
   1649     out.indent();
   1650 
   1651     out << "uint32_t _hidl_code,\n"
   1652         << "const ::android::hardware::Parcel &_hidl_data,\n"
   1653         << "::android::hardware::Parcel *_hidl_reply,\n"
   1654         << "uint32_t _hidl_flags,\n"
   1655         << "TransactCallback _hidl_cb) {\n";
   1656 
   1657     out.unindent();
   1658 
   1659     out << "::android::status_t _hidl_err = ::android::OK;\n\n";
   1660     out << "switch (_hidl_code) {\n";
   1661     out.indent();
   1662 
   1663     for (const auto &tuple : iface->allMethodsFromRoot()) {
   1664         const Method *method = tuple.method();
   1665         const Interface *superInterface = tuple.interface();
   1666 
   1667         out << "case "
   1668             << method->getSerialId()
   1669             << " /* "
   1670             << method->name()
   1671             << " */:\n{\n";
   1672 
   1673         out.indent();
   1674 
   1675         status_t err = generateStubSourceForMethod(out, method, superInterface);
   1676 
   1677         if (err != OK) {
   1678             return err;
   1679         }
   1680 
   1681         out.unindent();
   1682         out << "}\n\n";
   1683     }
   1684 
   1685     out << "default:\n{\n";
   1686     out.indent();
   1687 
   1688     if (iface->isIBase()) {
   1689         out << "(void)_hidl_flags;\n";
   1690         out << "return ::android::UNKNOWN_TRANSACTION;\n";
   1691     } else {
   1692         out << "return ";
   1693         out << gIBaseFqName.getInterfaceStubFqName().cppName();
   1694         out << "::onTransact(\n";
   1695 
   1696         out.indent();
   1697         out.indent();
   1698 
   1699         out << "_hidl_code, _hidl_data, _hidl_reply, "
   1700             << "_hidl_flags, _hidl_cb);\n";
   1701 
   1702         out.unindent();
   1703         out.unindent();
   1704     }
   1705 
   1706     out.unindent();
   1707     out << "}\n";
   1708 
   1709     out.unindent();
   1710     out << "}\n\n";
   1711 
   1712     out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
   1713         out << "_hidl_err = ::android::hardware::writeToParcel(\n";
   1714         out.indent(2, [&] {
   1715             out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
   1716             out << "_hidl_reply);\n";
   1717         });
   1718     });
   1719 
   1720     out << "return _hidl_err;\n";
   1721 
   1722     out.unindent();
   1723     out << "}\n\n";
   1724 
   1725     return OK;
   1726 }
   1727 
   1728 status_t AST::generateStubSourceForMethod(
   1729         Formatter &out,
   1730         const Method *method,
   1731         const Interface* superInterface) const {
   1732 
   1733     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
   1734         method->cppImpl(IMPL_STUB, out);
   1735         out << "break;\n";
   1736         return OK;
   1737     }
   1738 
   1739     out << "_hidl_err = "
   1740         << superInterface->fqName().cppNamespace()
   1741         << "::"
   1742         << superInterface->getStubName()
   1743         << "::_hidl_"
   1744         << method->name()
   1745         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
   1746     out << "break;\n";
   1747 
   1748     return OK;
   1749 }
   1750 
   1751 status_t AST::generateStaticStubMethodSource(Formatter &out,
   1752                                              const std::string &klassName,
   1753                                              const Method *method) const {
   1754     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
   1755         return OK;
   1756     }
   1757 
   1758     out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
   1759 
   1760     out.indent();
   1761     out.indent();
   1762 
   1763     out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
   1764         << "const ::android::hardware::Parcel &_hidl_data,\n"
   1765         << "::android::hardware::Parcel *_hidl_reply,\n"
   1766         << "TransactCallback _hidl_cb) {\n";
   1767 
   1768     out.unindent();
   1769 
   1770     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   1771     out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
   1772     out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
   1773     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
   1774 
   1775     out << "::android::status_t _hidl_err = ::android::OK;\n";
   1776 
   1777     out << "if (!_hidl_data.enforceInterface("
   1778         << klassName
   1779         << "::Pure::descriptor)) {\n";
   1780 
   1781     out.indent();
   1782     out << "_hidl_err = ::android::BAD_TYPE;\n";
   1783     out << "return _hidl_err;\n";
   1784     out.unindent();
   1785     out << "}\n\n";
   1786 
   1787     declareCppReaderLocals(out, method->args(), false /* forResults */);
   1788 
   1789     // First DFS: write buffers
   1790     for (const auto &arg : method->args()) {
   1791         emitCppReaderWriter(
   1792                 out,
   1793                 "_hidl_data",
   1794                 false /* parcelObjIsPointer */,
   1795                 arg,
   1796                 true /* reader */,
   1797                 Type::ErrorMode_Return,
   1798                 false /* addPrefixToName */);
   1799     }
   1800 
   1801     // Second DFS: resolve references
   1802     for (const auto &arg : method->args()) {
   1803         emitCppResolveReferences(
   1804                 out,
   1805                 "_hidl_data",
   1806                 false /* parcelObjIsPointer */,
   1807                 arg,
   1808                 true /* reader */,
   1809                 Type::ErrorMode_Return,
   1810                 false /* addPrefixToName */);
   1811     }
   1812 
   1813     generateCppInstrumentationCall(
   1814             out,
   1815             InstrumentationEvent::SERVER_API_ENTRY,
   1816             method);
   1817 
   1818     const bool returnsValue = !method->results().empty();
   1819     const TypedVar *elidedReturn = method->canElideCallback();
   1820 
   1821     std::string callee;
   1822 
   1823     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
   1824         callee = "_hidl_this";
   1825     } else {
   1826         callee = "static_cast<" + klassName + "*>(_hidl_this)->_hidl_mImpl";
   1827     }
   1828 
   1829     if (elidedReturn != nullptr) {
   1830         out << elidedReturn->type().getCppResultType()
   1831             << " _hidl_out_"
   1832             << elidedReturn->name()
   1833             << " = "
   1834             << callee << "->" << method->name()
   1835             << "(";
   1836 
   1837         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
   1838             if (arg->type().resultNeedsDeref()) {
   1839                 out << "*";
   1840             }
   1841             out << arg->name();
   1842         });
   1843 
   1844         out << ");\n\n";
   1845         out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
   1846             << "_hidl_reply);\n\n";
   1847 
   1848         elidedReturn->type().emitReaderWriter(
   1849                 out,
   1850                 "_hidl_out_" + elidedReturn->name(),
   1851                 "_hidl_reply",
   1852                 true, /* parcelObjIsPointer */
   1853                 false, /* isReader */
   1854                 Type::ErrorMode_Ignore);
   1855 
   1856         emitCppResolveReferences(
   1857                 out,
   1858                 "_hidl_reply",
   1859                 true /* parcelObjIsPointer */,
   1860                 elidedReturn,
   1861                 false /* reader */,
   1862                 Type::ErrorMode_Ignore,
   1863                 true /* addPrefixToName */);
   1864 
   1865         generateCppInstrumentationCall(
   1866                 out,
   1867                 InstrumentationEvent::SERVER_API_EXIT,
   1868                 method);
   1869 
   1870         out << "_hidl_cb(*_hidl_reply);\n";
   1871     } else {
   1872         if (returnsValue) {
   1873             out << "bool _hidl_callbackCalled = false;\n\n";
   1874         }
   1875 
   1876         out << callee << "->" << method->name() << "(";
   1877 
   1878         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
   1879             if (arg->type().resultNeedsDeref()) {
   1880                 out << "*";
   1881             }
   1882 
   1883             out << arg->name();
   1884         });
   1885 
   1886         if (returnsValue) {
   1887             if (!method->args().empty()) {
   1888                 out << ", ";
   1889             }
   1890 
   1891             out << "[&](";
   1892 
   1893             out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
   1894                 out << "const auto &_hidl_out_" << arg->name();
   1895             });
   1896 
   1897             out << ") {\n";
   1898             out.indent();
   1899             out << "if (_hidl_callbackCalled) {\n";
   1900             out.indent();
   1901             out << "LOG_ALWAYS_FATAL(\""
   1902                 << method->name()
   1903                 << ": _hidl_cb called a second time, but must be called once.\");\n";
   1904             out.unindent();
   1905             out << "}\n";
   1906             out << "_hidl_callbackCalled = true;\n\n";
   1907 
   1908             out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
   1909                 << "_hidl_reply);\n\n";
   1910 
   1911             // First DFS: buffers
   1912             for (const auto &arg : method->results()) {
   1913                 emitCppReaderWriter(
   1914                         out,
   1915                         "_hidl_reply",
   1916                         true /* parcelObjIsPointer */,
   1917                         arg,
   1918                         false /* reader */,
   1919                         Type::ErrorMode_Ignore,
   1920                         true /* addPrefixToName */);
   1921             }
   1922 
   1923             // Second DFS: resolve references
   1924             for (const auto &arg : method->results()) {
   1925                 emitCppResolveReferences(
   1926                         out,
   1927                         "_hidl_reply",
   1928                         true /* parcelObjIsPointer */,
   1929                         arg,
   1930                         false /* reader */,
   1931                         Type::ErrorMode_Ignore,
   1932                         true /* addPrefixToName */);
   1933             }
   1934 
   1935             generateCppInstrumentationCall(
   1936                     out,
   1937                     InstrumentationEvent::SERVER_API_EXIT,
   1938                     method);
   1939 
   1940             out << "_hidl_cb(*_hidl_reply);\n";
   1941 
   1942             out.unindent();
   1943             out << "});\n\n";
   1944         } else {
   1945             out << ");\n\n";
   1946             out << "(void) _hidl_cb;\n\n";
   1947             generateCppInstrumentationCall(
   1948                     out,
   1949                     InstrumentationEvent::SERVER_API_EXIT,
   1950                     method);
   1951         }
   1952 
   1953         if (returnsValue) {
   1954             out << "if (!_hidl_callbackCalled) {\n";
   1955             out.indent();
   1956             out << "LOG_ALWAYS_FATAL(\""
   1957                 << method->name()
   1958                 << ": _hidl_cb not called, but must be called once.\");\n";
   1959             out.unindent();
   1960             out << "}\n\n";
   1961         } else {
   1962             out << "::android::hardware::writeToParcel("
   1963                 << "::android::hardware::Status::ok(), "
   1964                 << "_hidl_reply);\n\n";
   1965         }
   1966     }
   1967 
   1968     out << "return _hidl_err;\n";
   1969     out.unindent();
   1970     out << "}\n\n";
   1971 
   1972     return OK;
   1973 }
   1974 
   1975 status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
   1976     if (!AST::isInterface()) {
   1977         // types.hal does not get a stub header.
   1978         return OK;
   1979     }
   1980 
   1981     const Interface* iface = mRootScope.getInterface();
   1982     CHECK(iface != nullptr);
   1983 
   1984     const std::string klassName = iface->getPassthroughName();
   1985 
   1986     bool supportOneway = iface->hasOnewayMethods();
   1987 
   1988     std::string path = outputPath;
   1989     path.append(mCoordinator->convertPackageRootToPath(mPackage));
   1990     path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
   1991     path.append(klassName);
   1992     path.append(".h");
   1993 
   1994     CHECK(Coordinator::MakeParentHierarchy(path));
   1995     FILE *file = fopen(path.c_str(), "w");
   1996 
   1997     if (file == NULL) {
   1998         return -errno;
   1999     }
   2000 
   2001     Formatter out(file);
   2002 
   2003     const std::string guard = makeHeaderGuard(klassName);
   2004 
   2005     out << "#ifndef " << guard << "\n";
   2006     out << "#define " << guard << "\n\n";
   2007 
   2008     std::vector<std::string> packageComponents;
   2009     getPackageAndVersionComponents(
   2010             &packageComponents, false /* cpp_compatible */);
   2011 
   2012     out << "#include <android-base/macros.h>\n";
   2013     out << "#include <cutils/trace.h>\n";
   2014     out << "#include <future>\n";
   2015 
   2016     generateCppPackageInclude(out, mPackage, iface->localName());
   2017     out << "\n";
   2018 
   2019     out << "#include <hidl/HidlPassthroughSupport.h>\n";
   2020     if (supportOneway) {
   2021         out << "#include <hidl/TaskRunner.h>\n";
   2022     }
   2023 
   2024     enterLeaveNamespace(out, true /* enter */);
   2025     out << "\n";
   2026 
   2027     out << "struct "
   2028         << klassName
   2029         << " : " << iface->localName()
   2030         << ", ::android::hardware::details::HidlInstrumentor {\n";
   2031 
   2032     out.indent();
   2033     out << "explicit "
   2034         << klassName
   2035         << "(const ::android::sp<"
   2036         << iface->localName()
   2037         << "> impl);\n";
   2038 
   2039     out.endl();
   2040     generateTemplatizationLink(out);
   2041 
   2042     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
   2043         return generatePassthroughMethod(out, method);
   2044     });
   2045 
   2046     if (err != OK) {
   2047         return err;
   2048     }
   2049 
   2050     out.unindent();
   2051     out << "private:\n";
   2052     out.indent();
   2053     out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
   2054 
   2055     if (supportOneway) {
   2056         out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
   2057 
   2058         out << "\n";
   2059 
   2060         out << "::android::hardware::Return<void> addOnewayTask("
   2061                "std::function<void(void)>);\n\n";
   2062     }
   2063 
   2064     out.unindent();
   2065 
   2066     out << "};\n\n";
   2067 
   2068     enterLeaveNamespace(out, false /* enter */);
   2069 
   2070     out << "\n#endif  // " << guard << "\n";
   2071 
   2072     return OK;
   2073 }
   2074 
   2075 status_t AST::generateInterfaceSource(Formatter &out) const {
   2076     const Interface* iface = mRootScope.getInterface();
   2077 
   2078     // generate castFrom functions
   2079     std::string childTypeResult = iface->getCppResultType();
   2080 
   2081     status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
   2082         bool reserved = method->isHidlReserved();
   2083 
   2084         if (!reserved) {
   2085             out << "// no default implementation for: ";
   2086         }
   2087         method->generateCppSignature(out, iface->localName());
   2088         if (reserved) {
   2089             out.block([&]() {
   2090                 method->cppImpl(IMPL_INTERFACE, out);
   2091             }).endl();
   2092         }
   2093 
   2094         out << "\n";
   2095 
   2096         return OK;
   2097     });
   2098     if (err != OK) {
   2099         return err;
   2100     }
   2101 
   2102     for (const Interface *superType : iface->typeChain()) {
   2103         out << "// static \n::android::hardware::Return<"
   2104             << childTypeResult
   2105             << "> "
   2106             << iface->localName()
   2107             << "::castFrom("
   2108             << superType->getCppArgumentType()
   2109             << " parent, bool "
   2110             << (iface == superType ? "/* emitError */" : "emitError")
   2111             << ") {\n";
   2112         out.indent();
   2113         if (iface == superType) {
   2114             out << "return parent;\n";
   2115         } else {
   2116             out << "return ::android::hardware::details::castInterface<";
   2117             out << iface->localName() << ", "
   2118                 << superType->fqName().cppName() << ", "
   2119                 << iface->getProxyName()
   2120                 << ">(\n";
   2121             out.indent();
   2122             out.indent();
   2123             out << "parent, \""
   2124                 << iface->fqName().string()
   2125                 << "\", emitError);\n";
   2126             out.unindent();
   2127             out.unindent();
   2128         }
   2129         out.unindent();
   2130         out << "}\n\n";
   2131     }
   2132 
   2133     return OK;
   2134 }
   2135 
   2136 status_t AST::generatePassthroughSource(Formatter &out) const {
   2137     const Interface* iface = mRootScope.getInterface();
   2138 
   2139     const std::string klassName = iface->getPassthroughName();
   2140 
   2141     out << klassName
   2142         << "::"
   2143         << klassName
   2144         << "(const ::android::sp<"
   2145         << iface->fullName()
   2146         << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
   2147         << mPackage.string()
   2148         << "\", \""
   2149         << iface->localName()
   2150         << "\"), mImpl(impl) {";
   2151     if (iface->hasOnewayMethods()) {
   2152         out << "\n";
   2153         out.indent([&] {
   2154             out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
   2155         });
   2156     }
   2157     out << "}\n\n";
   2158 
   2159     if (iface->hasOnewayMethods()) {
   2160         out << "::android::hardware::Return<void> "
   2161             << klassName
   2162             << "::addOnewayTask(std::function<void(void)> fun) {\n";
   2163         out.indent();
   2164         out << "if (!mOnewayQueue.push(fun)) {\n";
   2165         out.indent();
   2166         out << "return ::android::hardware::Status::fromExceptionCode(\n";
   2167         out.indent();
   2168         out.indent();
   2169         out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
   2170             << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
   2171         out.unindent();
   2172         out.unindent();
   2173         out.unindent();
   2174         out << "}\n";
   2175 
   2176         out << "return ::android::hardware::Status();\n";
   2177 
   2178         out.unindent();
   2179         out << "}\n\n";
   2180 
   2181 
   2182     }
   2183 
   2184     return OK;
   2185 }
   2186 
   2187 void AST::generateCppAtraceCall(Formatter &out,
   2188                                     InstrumentationEvent event,
   2189                                     const Method *method) const {
   2190     const Interface* iface = mRootScope.getInterface();
   2191     std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
   2192     switch (event) {
   2193         case SERVER_API_ENTRY:
   2194         {
   2195             out << "atrace_begin(ATRACE_TAG_HAL, \""
   2196                 << baseString + "::server\");\n";
   2197             break;
   2198         }
   2199         case CLIENT_API_ENTRY:
   2200         {
   2201             out << "atrace_begin(ATRACE_TAG_HAL, \""
   2202                 << baseString + "::client\");\n";
   2203             break;
   2204         }
   2205         case PASSTHROUGH_ENTRY:
   2206         {
   2207             out << "atrace_begin(ATRACE_TAG_HAL, \""
   2208                 << baseString + "::passthrough\");\n";
   2209             break;
   2210         }
   2211         case SERVER_API_EXIT:
   2212         case CLIENT_API_EXIT:
   2213         case PASSTHROUGH_EXIT:
   2214         {
   2215             out << "atrace_end(ATRACE_TAG_HAL);\n";
   2216             break;
   2217         }
   2218         default:
   2219         {
   2220             LOG(FATAL) << "Unsupported instrumentation event: " << event;
   2221         }
   2222     }
   2223 }
   2224 
   2225 void AST::generateCppInstrumentationCall(
   2226         Formatter &out,
   2227         InstrumentationEvent event,
   2228         const Method *method) const {
   2229     generateCppAtraceCall(out, event, method);
   2230 
   2231     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
   2232     out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
   2233     out.indent();
   2234     out << "std::vector<void *> _hidl_args;\n";
   2235     std::string event_str = "";
   2236     switch (event) {
   2237         case SERVER_API_ENTRY:
   2238         {
   2239             event_str = "InstrumentationEvent::SERVER_API_ENTRY";
   2240             for (const auto &arg : method->args()) {
   2241                 out << "_hidl_args.push_back((void *)"
   2242                     << (arg->type().resultNeedsDeref() ? "" : "&")
   2243                     << arg->name()
   2244                     << ");\n";
   2245             }
   2246             break;
   2247         }
   2248         case SERVER_API_EXIT:
   2249         {
   2250             event_str = "InstrumentationEvent::SERVER_API_EXIT";
   2251             for (const auto &arg : method->results()) {
   2252                 out << "_hidl_args.push_back((void *)&_hidl_out_"
   2253                     << arg->name()
   2254                     << ");\n";
   2255             }
   2256             break;
   2257         }
   2258         case CLIENT_API_ENTRY:
   2259         {
   2260             event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
   2261             for (const auto &arg : method->args()) {
   2262                 out << "_hidl_args.push_back((void *)&"
   2263                     << arg->name()
   2264                     << ");\n";
   2265             }
   2266             break;
   2267         }
   2268         case CLIENT_API_EXIT:
   2269         {
   2270             event_str = "InstrumentationEvent::CLIENT_API_EXIT";
   2271             for (const auto &arg : method->results()) {
   2272                 out << "_hidl_args.push_back((void *)"
   2273                     << (arg->type().resultNeedsDeref() ? "" : "&")
   2274                     << "_hidl_out_"
   2275                     << arg->name()
   2276                     << ");\n";
   2277             }
   2278             break;
   2279         }
   2280         case PASSTHROUGH_ENTRY:
   2281         {
   2282             event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
   2283             for (const auto &arg : method->args()) {
   2284                 out << "_hidl_args.push_back((void *)&"
   2285                     << arg->name()
   2286                     << ");\n";
   2287             }
   2288             break;
   2289         }
   2290         case PASSTHROUGH_EXIT:
   2291         {
   2292             event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
   2293             for (const auto &arg : method->results()) {
   2294                 out << "_hidl_args.push_back((void *)&_hidl_out_"
   2295                     << arg->name()
   2296                     << ");\n";
   2297             }
   2298             break;
   2299         }
   2300         default:
   2301         {
   2302             LOG(FATAL) << "Unsupported instrumentation event: " << event;
   2303         }
   2304     }
   2305 
   2306     const Interface* iface = mRootScope.getInterface();
   2307 
   2308     out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
   2309     out.indent();
   2310     out << "callback("
   2311         << event_str
   2312         << ", \""
   2313         << mPackage.package()
   2314         << "\", \""
   2315         << mPackage.version()
   2316         << "\", \""
   2317         << iface->localName()
   2318         << "\", \""
   2319         << method->name()
   2320         << "\", &_hidl_args);\n";
   2321     out.unindent();
   2322     out << "}\n";
   2323     out.unindent();
   2324     out << "}\n";
   2325     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
   2326 }
   2327 
   2328 }  // namespace android
   2329