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