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