• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Interface(const char * localName,const FQName & fullName,const Location & location,Scope * parent,const Reference<Type> & superType,const Hash * fileHash)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 
typeName() const75 std::string Interface::typeName() const {
76     return "interface " + localName();
77 }
78 
getFileHash() const79 const Hash* Interface::getFileHash() const {
80     return mFileHash;
81 }
82 
fillPingMethod(Method * method) const83 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 
fillLinkToDeathMethod(Method * method) const114 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 
fillUnlinkToDeathMethod(Method * method) const158 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 }
fillSyspropsChangedMethod(Method * method) const206 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 
fillSetHALInstrumentationMethod(Method * method) const224 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 
fillDescriptorChainMethod(Method * method) const257 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 
emitDigestChain(Formatter & out,const std::string & prefix,const std::vector<const Interface * > & chain,std::function<std::string (std::unique_ptr<ConstantExpression>)> byteToString) const291 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 
fillHashChainMethod(Method * method) const310 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 
fillGetDescriptorMethod(Method * method) const345 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 
fillGetDebugInfoMethod(Method * method) const367 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 << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
386                     out << "info.pid = -1;\n";
387                     out << "info.ptr = 0;\n";
388                     out << "info.arch = \n" << sArch << ";\n";
389                     out << "_hidl_cb(info);\n";
390                     out << "return ::android::hardware::Void();\n";
391                 }
392             },
393             {IMPL_STUB_IMPL,
394                 [](auto &out) {
395                     out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
396                     out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
397                     out << "info.ptr = ::android::hardware::details::debuggable()"
398                         << "? reinterpret_cast<uint64_t>(this) : 0;\n";
399                     out << "info.arch = \n" << sArch << ";\n";
400                     out << "_hidl_cb(info);\n";
401                     out << "return ::android::hardware::Void();\n";
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 
fillDebugMethod(Method * method) const419 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 
addMethod(Method * method)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 
getReferences() const462 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 
getConstantExpressions() const477 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 
getStrongReferences() const486 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 
resolveInheritance()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 
validate() const525 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 
getAlignmentAndSize(size_t * align,size_t * size) const545 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
546     *align = 8;
547     *size = 8;
548 }
549 
validateUniqueNames() const550 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 
validateAnnotations() const584 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 
addAllReservedMethods()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 
superType() const636 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 
typeChain() const646 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 
superTypeChain() const656 std::vector<const Interface *> Interface::superTypeChain() const {
657     return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
658 }
659 
isElidableType() const660 bool Interface::isElidableType() const {
661     return true;
662 }
663 
isInterface() const664 bool Interface::isInterface() const {
665     return true;
666 }
667 
isBinder() const668 bool Interface::isBinder() const {
669     return true;
670 }
671 
userDefinedMethods() const672 const std::vector<Method *> &Interface::userDefinedMethods() const {
673     return mUserMethods;
674 }
675 
hidlReservedMethods() const676 const std::vector<Method *> &Interface::hidlReservedMethods() const {
677     return mReservedMethods;
678 }
679 
methods() const680 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 
allMethodsFromRoot() const686 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 
allSuperMethodsFromRoot() const703 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
704     return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
705 }
706 
getBaseName() const707 std::string Interface::getBaseName() const {
708     return fqName().getInterfaceBaseName();
709 }
710 
getAdapterName() const711 std::string Interface::getAdapterName() const {
712     return fqName().getInterfaceAdapterName();
713 }
714 
getProxyName() const715 std::string Interface::getProxyName() const {
716     return fqName().getInterfaceProxyName();
717 }
718 
getStubName() const719 std::string Interface::getStubName() const {
720     return fqName().getInterfaceStubName();
721 }
722 
getHwName() const723 std::string Interface::getHwName() const {
724     return fqName().getInterfaceHwName();
725 }
726 
getPassthroughName() const727 std::string Interface::getPassthroughName() const {
728     return fqName().getInterfacePassthroughName();
729 }
730 
getProxyFqName() const731 FQName Interface::getProxyFqName() const {
732     return fqName().getInterfaceProxyFqName();
733 }
734 
getStubFqName() const735 FQName Interface::getStubFqName() const {
736     return fqName().getInterfaceStubFqName();
737 }
738 
getPassthroughFqName() const739 FQName Interface::getPassthroughFqName() const {
740     return fqName().getInterfacePassthroughFqName();
741 }
742 
getCppType(StorageMode mode,bool specifyNamespaces) const743 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 
getJavaType(bool) const761 std::string Interface::getJavaType(bool /* forInitializer */) const {
762     return fullJavaName();
763 }
764 
getVtsType() const765 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 
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const773 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 
emitPackageTypeDeclarations(Formatter & out) const848 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 
emitTypeDefinitions(Formatter & out,const std::string & prefix) const862 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 
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const868 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 
emitVtsAttributeDeclaration(Formatter & out) const888 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 
emitVtsMethodDeclaration(Formatter & out) const902 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 
emitVtsAttributeType(Formatter & out) const955 void Interface::emitVtsAttributeType(Formatter& out) const {
956     out << "type: " << getVtsType() << "\n"
957         << "predefined_type: \""
958         << fullName()
959         << "\"\n";
960 }
961 
hasOnewayMethods() const962 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 
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const978 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 
isNeverStrongReference() const992 bool Interface::isNeverStrongReference() const {
993     return true;
994 }
995 
996 }  // namespace android
997 
998