Home | History | Annotate | Download | only in hidl
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "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