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