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