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