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 "Interface.h" 18 19 #include "Annotation.h" 20 #include "ArrayType.h" 21 #include "ConstantExpression.h" 22 #include "DeathRecipientType.h" 23 #include "Method.h" 24 #include "ScalarType.h" 25 #include "StringType.h" 26 #include "VectorType.h" 27 28 #include <unistd.h> 29 30 #include <iostream> 31 #include <memory> 32 #include <sstream> 33 #include <unordered_map> 34 35 #include <android-base/logging.h> 36 #include <hidl-util/Formatter.h> 37 #include <hidl-util/StringHelper.h> 38 39 namespace android { 40 41 #define B_PACK_CHARS(c1, c2, c3, c4) \ 42 ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) 43 44 /* It is very important that these values NEVER change. These values 45 * must remain unchanged over the lifetime of android. This is 46 * because the framework on a device will be updated independently of 47 * the hals on a device. If the hals are compiled with one set of 48 * transaction values, and the framework with another, then the 49 * interface between them will be destroyed, and the device will not 50 * work. 51 */ 52 enum { 53 /////////////////// User defined transactions 54 FIRST_CALL_TRANSACTION = 0x00000001, 55 LAST_CALL_TRANSACTION = 0x0effffff, 56 /////////////////// HIDL reserved 57 FIRST_HIDL_TRANSACTION = 0x0f000000, 58 HIDL_PING_TRANSACTION = B_PACK_CHARS(0x0f, 'P', 'N', 'G'), 59 HIDL_DESCRIPTOR_CHAIN_TRANSACTION = B_PACK_CHARS(0x0f, 'C', 'H', 'N'), 60 HIDL_GET_DESCRIPTOR_TRANSACTION = B_PACK_CHARS(0x0f, 'D', 'S', 'C'), 61 HIDL_SYSPROPS_CHANGED_TRANSACTION = B_PACK_CHARS(0x0f, 'S', 'Y', 'S'), 62 HIDL_LINK_TO_DEATH_TRANSACTION = B_PACK_CHARS(0x0f, 'L', 'T', 'D'), 63 HIDL_UNLINK_TO_DEATH_TRANSACTION = B_PACK_CHARS(0x0f, 'U', 'T', 'D'), 64 HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION = B_PACK_CHARS(0x0f, 'I', 'N', 'T'), 65 HIDL_GET_REF_INFO_TRANSACTION = B_PACK_CHARS(0x0f, 'R', 'E', 'F'), 66 HIDL_DEBUG_TRANSACTION = B_PACK_CHARS(0x0f, 'D', 'B', 'G'), 67 HIDL_HASH_CHAIN_TRANSACTION = B_PACK_CHARS(0x0f, 'H', 'S', 'H'), 68 LAST_HIDL_TRANSACTION = 0x0fffffff, 69 }; 70 71 Interface::Interface(const char* localName, const FQName& fullName, const Location& location, 72 Scope* parent, const Reference<Type>& superType, const Hash* fileHash) 73 : Scope(localName, fullName, location, parent), mSuperType(superType), mFileHash(fileHash) {} 74 75 std::string Interface::typeName() const { 76 return "interface " + localName(); 77 } 78 79 const Hash* Interface::getFileHash() const { 80 return mFileHash; 81 } 82 83 bool Interface::fillPingMethod(Method *method) const { 84 if (method->name() != "ping") { 85 return false; 86 } 87 88 method->fillImplementation( 89 HIDL_PING_TRANSACTION, 90 { 91 {IMPL_INTERFACE, 92 [](auto &out) { 93 out << "return ::android::hardware::Void();\n"; 94 } 95 }, 96 {IMPL_STUB_IMPL, 97 [](auto &out) { 98 out << "return ::android::hardware::Void();\n"; 99 } 100 } 101 }, /*cppImpl*/ 102 { 103 {IMPL_INTERFACE, 104 [](auto &out) { 105 out << "return;\n"; 106 } 107 }, 108 } /*javaImpl*/ 109 ); 110 111 return true; 112 } 113 114 bool Interface::fillLinkToDeathMethod(Method *method) const { 115 if (method->name() != "linkToDeath") { 116 return false; 117 } 118 119 method->fillImplementation( 120 HIDL_LINK_TO_DEATH_TRANSACTION, 121 { 122 {IMPL_INTERFACE, 123 [](auto &out) { 124 out << "(void)cookie;\n" 125 << "return (recipient != nullptr);\n"; 126 } 127 }, 128 {IMPL_PROXY, 129 [](auto &out) { 130 out << "::android::hardware::ProcessState::self()->startThreadPool();\n"; 131 out << "::android::hardware::hidl_binder_death_recipient *binder_recipient" 132 << " = new ::android::hardware::hidl_binder_death_recipient(recipient, cookie, this);\n" 133 << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n" 134 << "_hidl_mDeathRecipients.push_back(binder_recipient);\n" 135 << "return (remote()->linkToDeath(binder_recipient)" 136 << " == ::android::OK);\n"; 137 } 138 }, 139 {IMPL_STUB, nullptr} 140 }, /*cppImpl*/ 141 { 142 {IMPL_INTERFACE, 143 [](auto &out) { 144 out << "return true;"; 145 } 146 }, 147 {IMPL_PROXY, 148 [](auto &out) { 149 out << "return mRemote.linkToDeath(recipient, cookie);\n"; 150 } 151 }, 152 {IMPL_STUB, nullptr} 153 } /*javaImpl*/ 154 ); 155 return true; 156 } 157 158 bool Interface::fillUnlinkToDeathMethod(Method *method) const { 159 if (method->name() != "unlinkToDeath") { 160 return false; 161 } 162 163 method->fillImplementation( 164 HIDL_UNLINK_TO_DEATH_TRANSACTION, 165 { 166 {IMPL_INTERFACE, 167 [](auto &out) { 168 out << "return (recipient != nullptr);\n"; 169 } 170 }, 171 {IMPL_PROXY, 172 [](auto &out) { 173 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n" 174 << "for (auto it = _hidl_mDeathRecipients.begin();" 175 << "it != _hidl_mDeathRecipients.end();" 176 << "++it) {\n"; 177 out.indent([&] { 178 out.sIf("(*it)->getRecipient() == recipient", [&] { 179 out << "::android::status_t status = remote()->unlinkToDeath(*it);\n" 180 << "_hidl_mDeathRecipients.erase(it);\n" 181 << "return status == ::android::OK;\n"; 182 }); 183 }); 184 out << "}\n"; 185 out << "return false;\n"; 186 } 187 }, 188 {IMPL_STUB, nullptr /* don't generate code */} 189 }, /*cppImpl*/ 190 { 191 {IMPL_INTERFACE, 192 [](auto &out) { 193 out << "return true;\n"; 194 } 195 }, 196 {IMPL_PROXY, 197 [](auto &out) { 198 out << "return mRemote.unlinkToDeath(recipient);\n"; 199 } 200 }, 201 {IMPL_STUB, nullptr /* don't generate code */} 202 } /*javaImpl*/ 203 ); 204 return true; 205 } 206 bool Interface::fillSyspropsChangedMethod(Method *method) const { 207 if (method->name() != "notifySyspropsChanged") { 208 return false; 209 } 210 211 method->fillImplementation( 212 HIDL_SYSPROPS_CHANGED_TRANSACTION, 213 { { IMPL_INTERFACE, [](auto &out) { 214 out << "::android::report_sysprop_change();\n"; 215 out << "return ::android::hardware::Void();"; 216 } } }, /*cppImpl */ 217 { { IMPL_INTERFACE, [](auto &out) { /* javaImpl */ 218 out << "android.os.HwBinder.enableInstrumentation();"; 219 } } } /*javaImpl */ 220 ); 221 return true; 222 } 223 224 bool Interface::fillSetHALInstrumentationMethod(Method *method) const { 225 if (method->name() != "setHALInstrumentation") { 226 return false; 227 } 228 229 method->fillImplementation( 230 HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION, 231 { 232 {IMPL_INTERFACE, 233 [](auto &out) { 234 // do nothing for base class. 235 out << "return ::android::hardware::Void();\n"; 236 } 237 }, 238 {IMPL_STUB, 239 [](auto &out) { 240 out << "configureInstrumentation();\n"; 241 } 242 }, 243 {IMPL_PASSTHROUGH, 244 [](auto &out) { 245 out << "configureInstrumentation();\n"; 246 out << "return ::android::hardware::Void();\n"; 247 } 248 }, 249 }, /*cppImpl */ 250 { { IMPL_INTERFACE, [](auto & /*out*/) { /* javaImpl */ 251 // Not support for Java Impl for now. 252 } } } /*javaImpl */ 253 ); 254 return true; 255 } 256 257 bool Interface::fillDescriptorChainMethod(Method *method) const { 258 if (method->name() != "interfaceChain") { 259 return false; 260 } 261 262 method->fillImplementation( 263 HIDL_DESCRIPTOR_CHAIN_TRANSACTION, 264 { { IMPL_INTERFACE, [this](auto &out) { 265 std::vector<const Interface *> chain = typeChain(); 266 out << "_hidl_cb("; 267 out.block([&] { 268 for (const Interface *iface : chain) { 269 out << iface->fullName() << "::descriptor,\n"; 270 } 271 }); 272 out << ");\n"; 273 out << "return ::android::hardware::Void();"; 274 } } }, /* cppImpl */ 275 { { IMPL_INTERFACE, [this](auto &out) { 276 std::vector<const Interface *> chain = typeChain(); 277 out << "return new java.util.ArrayList<String>(java.util.Arrays.asList(\n"; 278 out.indent(); out.indent(); 279 for (size_t i = 0; i < chain.size(); ++i) { 280 if (i != 0) 281 out << ",\n"; 282 out << chain[i]->fullJavaName() << ".kInterfaceName"; 283 } 284 out << "));"; 285 out.unindent(); out.unindent(); 286 } } } /* javaImpl */ 287 ); 288 return true; 289 } 290 291 void Interface::emitDigestChain( 292 Formatter& out, const std::string& prefix, const std::vector<const Interface*>& chain, 293 std::function<std::string(std::unique_ptr<ConstantExpression>)> byteToString) const { 294 out.join(chain.begin(), chain.end(), ",\n", [&](const auto& iface) { 295 out << prefix; 296 out << "{"; 297 out.join( 298 iface->getFileHash()->raw().begin(), iface->getFileHash()->raw().end(), ",", 299 [&](const auto& e) { 300 // Use ConstantExpression::cppValue / javaValue 301 // because Java used signed byte for uint8_t. 302 out << byteToString(ConstantExpression::ValueOf(ScalarType::Kind::KIND_UINT8, e)); 303 }); 304 out << "} /* "; 305 out << iface->getFileHash()->hexString(); 306 out << " */"; 307 }); 308 } 309 310 bool Interface::fillHashChainMethod(Method *method) const { 311 if (method->name() != "getHashChain") { 312 return false; 313 } 314 const VectorType *chainType = static_cast<const VectorType *>(&method->results()[0]->type()); 315 const ArrayType *digestType = static_cast<const ArrayType *>(chainType->getElementType()); 316 317 method->fillImplementation( 318 HIDL_HASH_CHAIN_TRANSACTION, 319 { { IMPL_INTERFACE, [this, digestType](auto &out) { 320 std::vector<const Interface *> chain = typeChain(); 321 out << "_hidl_cb("; 322 out.block([&] { 323 emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")", chain, 324 [](const auto& e) { return e->cppValue(); }); 325 }); 326 out << ");\n"; 327 out << "return ::android::hardware::Void();\n"; 328 } } }, /* cppImpl */ 329 { { IMPL_INTERFACE, [this, digestType, chainType](auto &out) { 330 std::vector<const Interface *> chain = typeChain(); 331 out << "return new " 332 << chainType->getJavaType(false /* forInitializer */) 333 << "(java.util.Arrays.asList(\n"; 334 out.indent(2, [&] { 335 // No need for dimensions when elements are explicitly provided. 336 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */), 337 chain, [](const auto& e) { return e->javaValue(); }); 338 }); 339 out << "));\n"; 340 } } } /* javaImpl */ 341 ); 342 return true; 343 } 344 345 bool Interface::fillGetDescriptorMethod(Method *method) const { 346 if (method->name() != "interfaceDescriptor") { 347 return false; 348 } 349 350 method->fillImplementation( 351 HIDL_GET_DESCRIPTOR_TRANSACTION, 352 { { IMPL_INTERFACE, [this](auto &out) { 353 out << "_hidl_cb(" 354 << fullName() 355 << "::descriptor);\n" 356 << "return ::android::hardware::Void();"; 357 } } }, /* cppImpl */ 358 { { IMPL_INTERFACE, [this](auto &out) { 359 out << "return " 360 << fullJavaName() 361 << ".kInterfaceName;\n"; 362 } } } /* javaImpl */ 363 ); 364 return true; 365 } 366 367 bool Interface::fillGetDebugInfoMethod(Method *method) const { 368 if (method->name() != "getDebugInfo") { 369 return false; 370 } 371 372 static const std::string sArch = 373 "#if defined(__LP64__)\n" 374 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n" 375 "#else\n" 376 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n" 377 "#endif\n"; 378 379 method->fillImplementation( 380 HIDL_GET_REF_INFO_TRANSACTION, 381 { 382 {IMPL_INTERFACE, 383 [](auto &out) { 384 // getDebugInfo returns N/A for local objects. 385 out << "_hidl_cb({ -1 /* pid */, 0 /* ptr */, \n" 386 << sArch 387 << "});\n" 388 << "return ::android::hardware::Void();"; 389 } 390 }, 391 {IMPL_STUB_IMPL, 392 [](auto &out) { 393 out << "_hidl_cb("; 394 out.block([&] { 395 out << "::android::hardware::details::getPidIfSharable(),\n" 396 << "::android::hardware::details::debuggable()" 397 << "? reinterpret_cast<uint64_t>(this) : 0 /* ptr */,\n" 398 << sArch << "\n"; 399 }); 400 out << ");\n" 401 << "return ::android::hardware::Void();"; 402 } 403 } 404 }, /* cppImpl */ 405 { { IMPL_INTERFACE, [method](auto &out) { 406 const Type &refInfo = method->results().front()->type(); 407 out << refInfo.getJavaType(false /* forInitializer */) << " info = new " 408 << refInfo.getJavaType(true /* forInitializer */) << "();\n" 409 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n" 410 << "info.ptr = 0;\n" 411 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n" 412 << "return info;"; 413 } } } /* javaImpl */ 414 ); 415 416 return true; 417 } 418 419 bool Interface::fillDebugMethod(Method *method) const { 420 if (method->name() != "debug") { 421 return false; 422 } 423 424 method->fillImplementation( 425 HIDL_DEBUG_TRANSACTION, 426 { 427 {IMPL_INTERFACE, 428 [](auto &out) { 429 out << "(void)fd;\n" 430 << "(void)options;\n" 431 << "return ::android::hardware::Void();"; 432 } 433 }, 434 }, /* cppImpl */ 435 { 436 /* unused, as the debug method is hidden from Java */ 437 } /* javaImpl */ 438 ); 439 440 return true; 441 } 442 443 static std::map<std::string, Method *> gAllReservedMethods; 444 445 bool Interface::addMethod(Method *method) { 446 if (isIBase()) { 447 if (!gAllReservedMethods.emplace(method->name(), method).second) { 448 std::cerr << "ERROR: hidl-gen encountered duplicated reserved method " << method->name() 449 << std::endl; 450 return false; 451 } 452 // will add it in addAllReservedMethods 453 return true; 454 } 455 456 CHECK(!method->isHidlReserved()); 457 mUserMethods.push_back(method); 458 459 return true; 460 } 461 462 std::vector<const Reference<Type>*> Interface::getReferences() const { 463 std::vector<const Reference<Type>*> ret; 464 465 if (!isIBase()) { 466 ret.push_back(&mSuperType); 467 } 468 469 for (const auto* method : methods()) { 470 const auto& references = method->getReferences(); 471 ret.insert(ret.end(), references.begin(), references.end()); 472 } 473 474 return ret; 475 } 476 477 std::vector<const ConstantExpression*> Interface::getConstantExpressions() const { 478 std::vector<const ConstantExpression*> ret; 479 for (const auto* method : methods()) { 480 const auto& retMethod = method->getConstantExpressions(); 481 ret.insert(ret.end(), retMethod.begin(), retMethod.end()); 482 } 483 return ret; 484 } 485 486 std::vector<const Reference<Type>*> Interface::getStrongReferences() const { 487 // Interface is a special case as a reference: 488 // its definiton must be completed for extension but 489 // not necessary for other references. 490 491 std::vector<const Reference<Type>*> ret; 492 if (!isIBase()) { 493 ret.push_back(&mSuperType); 494 } 495 496 for (const auto* method : methods()) { 497 const auto& references = method->getStrongReferences(); 498 ret.insert(ret.end(), references.begin(), references.end()); 499 } 500 501 return ret; 502 } 503 504 status_t Interface::resolveInheritance() { 505 size_t serial = FIRST_CALL_TRANSACTION; 506 for (const auto* ancestor : superTypeChain()) { 507 serial += ancestor->mUserMethods.size(); 508 } 509 510 for (Method* method : mUserMethods) { 511 if (serial > LAST_CALL_TRANSACTION) { 512 std::cerr << "ERROR: More than " << LAST_CALL_TRANSACTION 513 << " methods (including super and reserved) are not allowed at " << location() 514 << std::endl; 515 return UNKNOWN_ERROR; 516 } 517 518 method->setSerialId(serial); 519 serial++; 520 } 521 522 return Scope::resolveInheritance(); 523 } 524 525 status_t Interface::validate() const { 526 CHECK(isIBase() == mSuperType.isEmptyReference()); 527 528 if (!isIBase() && !mSuperType->isInterface()) { 529 std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location() 530 << std::endl; 531 return UNKNOWN_ERROR; 532 } 533 534 status_t err; 535 536 err = validateUniqueNames(); 537 if (err != OK) return err; 538 539 err = validateAnnotations(); 540 if (err != OK) return err; 541 542 return Scope::validate(); 543 } 544 545 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const { 546 *align = 8; 547 *size = 8; 548 } 549 550 status_t Interface::validateUniqueNames() const { 551 std::unordered_map<std::string, const Interface*> registeredMethodNames; 552 for (auto const& tuple : allSuperMethodsFromRoot()) { 553 // No need to check super method uniqueness 554 registeredMethodNames[tuple.method()->name()] = tuple.interface(); 555 } 556 557 for (const Method* method : mUserMethods) { 558 auto registered = registeredMethodNames.find(method->name()); 559 560 if (registered != registeredMethodNames.end()) { 561 const Interface* definedInType = registered->second; 562 563 if (definedInType == this) { 564 // Defined in this interface 565 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'"; 566 } else if (definedInType->isIBase()) { 567 // Defined in IBase 568 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'"; 569 } else { 570 // Defined in super not IBase 571 std::cerr << "ERROR: Redefinition of method '" << method->name() 572 << "' defined in interface '" << definedInType->fullName() << "'"; 573 } 574 std::cerr << " at " << method->location() << std::endl; 575 return UNKNOWN_ERROR; 576 } 577 578 registeredMethodNames[method->name()] = this; 579 } 580 581 return OK; 582 } 583 584 status_t Interface::validateAnnotations() const { 585 for (const Method* method : methods()) { 586 for (const Annotation* annotation : method->annotations()) { 587 const std::string name = annotation->name(); 588 589 if (name == "entry" || name == "exit" || name == "callflow") { 590 continue; 591 } 592 593 std::cerr << "ERROR: Unrecognized annotation '" << name 594 << "' for method: " << method->name() << ". An annotation should be one of: " 595 << "entry, exit, callflow." << std::endl; 596 return UNKNOWN_ERROR; 597 } 598 } 599 return OK; 600 } 601 602 bool Interface::addAllReservedMethods() { 603 // use a sorted map to insert them in serial ID order. 604 std::map<int32_t, Method *> reservedMethodsById; 605 for (const auto &pair : gAllReservedMethods) { 606 Method *method = pair.second->copySignature(); 607 bool fillSuccess = fillPingMethod(method) 608 || fillDescriptorChainMethod(method) 609 || fillGetDescriptorMethod(method) 610 || fillHashChainMethod(method) 611 || fillSyspropsChangedMethod(method) 612 || fillLinkToDeathMethod(method) 613 || fillUnlinkToDeathMethod(method) 614 || fillSetHALInstrumentationMethod(method) 615 || fillGetDebugInfoMethod(method) 616 || fillDebugMethod(method); 617 618 if (!fillSuccess) { 619 std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name() 620 << std::endl; 621 return false; 622 } 623 if (!reservedMethodsById.emplace(method->getSerialId(), method).second) { 624 std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name() 625 << " and " << reservedMethodsById[method->getSerialId()]->name() 626 << ", serialId = " << method->getSerialId() << std::endl; 627 return false; 628 } 629 } 630 for (const auto &pair : reservedMethodsById) { 631 this->mReservedMethods.push_back(pair.second); 632 } 633 return true; 634 } 635 636 const Interface* Interface::superType() const { 637 if (isIBase()) return nullptr; 638 if (!mSuperType->isInterface()) { 639 // This is actually an error 640 // that would be caught in validate 641 return nullptr; 642 } 643 return static_cast<const Interface*>(mSuperType.get()); 644 } 645 646 std::vector<const Interface *> Interface::typeChain() const { 647 std::vector<const Interface *> v; 648 const Interface *iface = this; 649 while (iface != nullptr) { 650 v.push_back(iface); 651 iface = iface->superType(); 652 } 653 return v; 654 } 655 656 std::vector<const Interface *> Interface::superTypeChain() const { 657 return isIBase() ? std::vector<const Interface*>() : superType()->typeChain(); 658 } 659 660 bool Interface::isElidableType() const { 661 return true; 662 } 663 664 bool Interface::isInterface() const { 665 return true; 666 } 667 668 bool Interface::isBinder() const { 669 return true; 670 } 671 672 const std::vector<Method *> &Interface::userDefinedMethods() const { 673 return mUserMethods; 674 } 675 676 const std::vector<Method *> &Interface::hidlReservedMethods() const { 677 return mReservedMethods; 678 } 679 680 std::vector<Method *> Interface::methods() const { 681 std::vector<Method *> v(mUserMethods); 682 v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end()); 683 return v; 684 } 685 686 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const { 687 std::vector<InterfaceAndMethod> v; 688 std::vector<const Interface *> chain = typeChain(); 689 for (auto it = chain.rbegin(); it != chain.rend(); ++it) { 690 const Interface *iface = *it; 691 for (Method *userMethod : iface->userDefinedMethods()) { 692 v.push_back(InterfaceAndMethod(iface, userMethod)); 693 } 694 } 695 for (Method *reservedMethod : hidlReservedMethods()) { 696 v.push_back(InterfaceAndMethod( 697 *chain.rbegin(), // IBase 698 reservedMethod)); 699 } 700 return v; 701 } 702 703 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const { 704 return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot(); 705 } 706 707 std::string Interface::getBaseName() const { 708 return fqName().getInterfaceBaseName(); 709 } 710 711 std::string Interface::getAdapterName() const { 712 return fqName().getInterfaceAdapterName(); 713 } 714 715 std::string Interface::getProxyName() const { 716 return fqName().getInterfaceProxyName(); 717 } 718 719 std::string Interface::getStubName() const { 720 return fqName().getInterfaceStubName(); 721 } 722 723 std::string Interface::getHwName() const { 724 return fqName().getInterfaceHwName(); 725 } 726 727 std::string Interface::getPassthroughName() const { 728 return fqName().getInterfacePassthroughName(); 729 } 730 731 FQName Interface::getProxyFqName() const { 732 return fqName().getInterfaceProxyFqName(); 733 } 734 735 FQName Interface::getStubFqName() const { 736 return fqName().getInterfaceStubFqName(); 737 } 738 739 FQName Interface::getPassthroughFqName() const { 740 return fqName().getInterfacePassthroughFqName(); 741 } 742 743 std::string Interface::getCppType(StorageMode mode, 744 bool specifyNamespaces) const { 745 const std::string base = 746 std::string(specifyNamespaces ? "::android::" : "") 747 + "sp<" 748 + fullName() 749 + ">"; 750 751 switch (mode) { 752 case StorageMode_Stack: 753 case StorageMode_Result: 754 return base; 755 756 case StorageMode_Argument: 757 return "const " + base + "&"; 758 } 759 } 760 761 std::string Interface::getJavaType(bool /* forInitializer */) const { 762 return fullJavaName(); 763 } 764 765 std::string Interface::getVtsType() const { 766 if (StringHelper::EndsWith(localName(), "Callback")) { 767 return "TYPE_HIDL_CALLBACK"; 768 } else { 769 return "TYPE_HIDL_INTERFACE"; 770 } 771 } 772 773 void Interface::emitReaderWriter( 774 Formatter &out, 775 const std::string &name, 776 const std::string &parcelObj, 777 bool parcelObjIsPointer, 778 bool isReader, 779 ErrorMode mode) const { 780 const std::string parcelObjDeref = 781 parcelObj + (parcelObjIsPointer ? "->" : "."); 782 783 if (isReader) { 784 out << "{\n"; 785 out.indent(); 786 787 const std::string binderName = "_hidl_binder"; 788 out << "::android::sp<::android::hardware::IBinder> " 789 << binderName << ";\n"; 790 791 out << "_hidl_err = "; 792 out << parcelObjDeref 793 << "readNullableStrongBinder(&" 794 << binderName 795 << ");\n"; 796 797 handleError(out, mode); 798 799 out << name 800 << " = " 801 << "::android::hardware::fromBinder<" 802 << fqName().cppName() 803 << "," 804 << getProxyFqName().cppName() 805 << "," 806 << getStubFqName().cppName() 807 << ">(" 808 << binderName 809 << ");\n"; 810 811 out.unindent(); 812 out << "}\n\n"; 813 } else { 814 out << "if (" << name << " == nullptr) {\n"; 815 out.indent(); 816 out << "_hidl_err = "; 817 out << parcelObjDeref 818 << "writeStrongBinder(nullptr);\n"; 819 out.unindent(); 820 out << "} else {\n"; 821 out.indent(); 822 out << "::android::sp<::android::hardware::IBinder> _hidl_binder = " 823 << "::android::hardware::toBinder<\n"; 824 out.indent(2, [&] { 825 out << fqName().cppName() 826 << ">(" 827 << name 828 << ");\n"; 829 }); 830 out << "if (_hidl_binder.get() != nullptr) {\n"; 831 out.indent([&] { 832 out << "_hidl_err = " 833 << parcelObjDeref 834 << "writeStrongBinder(_hidl_binder);\n"; 835 }); 836 out << "} else {\n"; 837 out.indent([&] { 838 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n"; 839 }); 840 out << "}\n"; 841 out.unindent(); 842 out << "}\n"; 843 844 handleError(out, mode); 845 } 846 } 847 848 void Interface::emitPackageTypeDeclarations(Formatter& out) const { 849 Scope::emitPackageTypeDeclarations(out); 850 851 out << "static inline std::string toString(" << getCppArgumentType() << " o) "; 852 853 out.block([&] { 854 out << "std::string os = \"[class or subclass of \";\n" 855 << "os += " << fullName() << "::descriptor;\n" 856 << "os += \"]\";\n" 857 << "os += o->isRemote() ? \"@remote\" : \"@local\";\n" 858 << "return os;\n"; 859 }).endl().endl(); 860 } 861 862 void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const { 863 std::string space = prefix.empty() ? "" : (prefix + "::"); 864 865 Scope::emitTypeDefinitions(out, space + localName()); 866 } 867 868 void Interface::emitJavaReaderWriter( 869 Formatter &out, 870 const std::string &parcelObj, 871 const std::string &argName, 872 bool isReader) const { 873 if (isReader) { 874 out << fullJavaName() 875 << ".asInterface(" 876 << parcelObj 877 << ".readStrongBinder());\n"; 878 } else { 879 out << parcelObj 880 << ".writeStrongBinder(" 881 << argName 882 << " == null ? null : " 883 << argName 884 << ".asBinder());\n"; 885 } 886 } 887 888 void Interface::emitVtsAttributeDeclaration(Formatter& out) const { 889 for (const auto &type : getSubTypes()) { 890 // Skip for TypeDef as it is just an alias of a defined type. 891 if (type->isTypeDef()) { 892 continue; 893 } 894 out << "attribute: {\n"; 895 out.indent(); 896 type->emitVtsTypeDeclarations(out); 897 out.unindent(); 898 out << "}\n\n"; 899 } 900 } 901 902 void Interface::emitVtsMethodDeclaration(Formatter& out) const { 903 for (const auto &method : methods()) { 904 if (method->isHidlReserved()) { 905 continue; 906 } 907 908 out << "api: {\n"; 909 out.indent(); 910 out << "name: \"" << method->name() << "\"\n"; 911 // Generate declaration for each return value. 912 for (const auto &result : method->results()) { 913 out << "return_type_hidl: {\n"; 914 out.indent(); 915 result->type().emitVtsAttributeType(out); 916 out.unindent(); 917 out << "}\n"; 918 } 919 // Generate declaration for each input argument 920 for (const auto &arg : method->args()) { 921 out << "arg: {\n"; 922 out.indent(); 923 arg->type().emitVtsAttributeType(out); 924 out.unindent(); 925 out << "}\n"; 926 } 927 // Generate declaration for each annotation. 928 for (const auto &annotation : method->annotations()) { 929 out << "callflow: {\n"; 930 out.indent(); 931 const std::string name = annotation->name(); 932 if (name == "entry") { 933 out << "entry: true\n"; 934 } else if (name == "exit") { 935 out << "exit: true\n"; 936 } else if (name == "callflow") { 937 const AnnotationParam *param = 938 annotation->getParam("next"); 939 if (param != nullptr) { 940 for (const auto& value : param->getValues()) { 941 out << "next: " << value << "\n"; 942 } 943 } 944 } else { 945 CHECK(false); 946 } 947 out.unindent(); 948 out << "}\n"; 949 } 950 out.unindent(); 951 out << "}\n\n"; 952 } 953 } 954 955 void Interface::emitVtsAttributeType(Formatter& out) const { 956 out << "type: " << getVtsType() << "\n" 957 << "predefined_type: \"" 958 << fullName() 959 << "\"\n"; 960 } 961 962 bool Interface::hasOnewayMethods() const { 963 for (auto const &method : methods()) { 964 if (method->isOneway()) { 965 return true; 966 } 967 } 968 969 const Interface* superClass = superType(); 970 971 if (superClass != nullptr) { 972 return superClass->hasOnewayMethods(); 973 } 974 975 return false; 976 } 977 978 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const { 979 if (superType() != nullptr && !superType()->isJavaCompatible(visited)) { 980 return false; 981 } 982 983 for (const auto* method : methods()) { 984 if (!method->deepIsJavaCompatible(visited)) { 985 return false; 986 } 987 } 988 989 return Scope::isJavaCompatible(visited); 990 } 991 992 bool Interface::isNeverStrongReference() const { 993 return true; 994 } 995 996 } // namespace android 997 998