1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Interface.h"
18 
19 #include "Annotation.h"
20 #include "ArrayType.h"
21 #include "ConstantExpression.h"
22 #include "DeathRecipientType.h"
23 #include "Method.h"
24 #include "ScalarType.h"
25 #include "StringType.h"
26 #include "VectorType.h"
27 
28 #include <unistd.h>
29 
30 #include <iostream>
31 #include <memory>
32 #include <sstream>
33 #include <string>
34 #include <unordered_map>
35 
36 #include <android-base/logging.h>
37 #include <hidl-util/Formatter.h>
38 #include <hidl-util/StringHelper.h>
39 #include <hwbinder/IBinder.h>
40 
41 namespace android {
42 
43 const std::unique_ptr<ConstantExpression> Interface::FLAG_ONE_WAY =
44         std::make_unique<LiteralConstantExpression>(ScalarType::KIND_UINT32,
45                                                     hardware::IBinder::FLAG_ONEWAY, "oneway");
46 const std::unique_ptr<ConstantExpression> Interface::FLAG_CLEAR_BUF =
47         std::make_unique<LiteralConstantExpression>(ScalarType::KIND_UINT32,
48                                                     hardware::IBinder::FLAG_CLEAR_BUF, "clear buf");
49 
Interface(const std::string & localName,const FQName & fullName,const Location & location,Scope * parent,const Reference<Type> & superType,const Hash * fileHash)50 Interface::Interface(const std::string& localName, const FQName& fullName, const Location& location,
51                      Scope* parent, const Reference<Type>& superType, const Hash* fileHash)
52     : Scope(localName, fullName, location, parent), mSuperType(superType), mFileHash(fileHash) {}
53 
typeName() const54 std::string Interface::typeName() const {
55     return "interface " + definedName();
56 }
57 
getFileHash() const58 const Hash* Interface::getFileHash() const {
59     return mFileHash;
60 }
61 
fillPingMethod(Method * method) const62 bool Interface::fillPingMethod(Method *method) const {
63     if (method->name() != "ping") {
64         return false;
65     }
66 
67     method->fillImplementation(
68         hardware::IBinder::HIDL_PING_TRANSACTION,
69         {
70             {IMPL_INTERFACE,
71                 [](auto &out) {
72                     out << "return ::android::hardware::Void();\n";
73                 }
74             },
75             {IMPL_STUB_IMPL,
76                 [](auto &out) {
77                     out << "return ::android::hardware::Void();\n";
78                 }
79             }
80         }, /*cppImpl*/
81         {
82             {IMPL_INTERFACE,
83                 [](auto &out) {
84                     out << "return;\n";
85                 }
86             },
87         } /*javaImpl*/
88     );
89 
90     return true;
91 }
92 
fillLinkToDeathMethod(Method * method) const93 bool Interface::fillLinkToDeathMethod(Method *method) const {
94     if (method->name() != "linkToDeath") {
95         return false;
96     }
97 
98     method->fillImplementation(
99             hardware::IBinder::HIDL_LINK_TO_DEATH_TRANSACTION,
100             {
101                 {IMPL_INTERFACE,
102                     [](auto &out) {
103                         out << "(void)cookie;\n"
104                             << "return (recipient != nullptr);\n";
105                     }
106                 },
107                 {IMPL_PROXY,
108                     [](auto &out) {
109                         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
110                         out << "::android::hardware::hidl_binder_death_recipient *binder_recipient"
111                             << " = new ::android::hardware::hidl_binder_death_recipient(recipient, cookie, this);\n"
112                             << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
113                             << "_hidl_mDeathRecipients.push_back(binder_recipient);\n"
114                             << "return (remote()->linkToDeath(binder_recipient)"
115                             << " == ::android::OK);\n";
116                     }
117                 },
118                 {IMPL_STUB, nullptr}
119             }, /*cppImpl*/
120             {
121                 {IMPL_INTERFACE,
122                     [](auto &out) {
123                         out << "return true;\n";
124                     }
125                 },
126                 {IMPL_PROXY,
127                     [](auto &out) {
128                         out << "return mRemote.linkToDeath(recipient, cookie);\n";
129                     }
130                 },
131                 {IMPL_STUB, nullptr}
132             } /*javaImpl*/
133     );
134     return true;
135 }
136 
fillUnlinkToDeathMethod(Method * method) const137 bool Interface::fillUnlinkToDeathMethod(Method *method) const {
138     if (method->name() != "unlinkToDeath") {
139         return false;
140     }
141 
142     method->fillImplementation(
143             hardware::IBinder::HIDL_UNLINK_TO_DEATH_TRANSACTION,
144             {
145                 {IMPL_INTERFACE,
146                     [](auto &out) {
147                         out << "return (recipient != nullptr);\n";
148                     }
149                 },
150                 {IMPL_PROXY,
151                     [](auto &out) {
152                         out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
153                             << "for (auto it = _hidl_mDeathRecipients.rbegin();"
154                             << "it != _hidl_mDeathRecipients.rend();"
155                             << "++it) {\n";
156                         out.indent([&] {
157                             out.sIf("(*it)->getRecipient() == recipient", [&] {
158                                 out << "::android::status_t status = remote()->unlinkToDeath(*it);\n"
159                                     << "_hidl_mDeathRecipients.erase(it.base()-1);\n"
160                                     << "return status == ::android::OK;\n";
161                                 });
162                             }).endl();
163                         out << "}\n";
164                         out << "return false;\n";
165                     }
166                 },
167                 {IMPL_STUB, nullptr /* don't generate code */}
168             }, /*cppImpl*/
169             {
170                 {IMPL_INTERFACE,
171                     [](auto &out) {
172                         out << "return true;\n";
173                     }
174                 },
175                 {IMPL_PROXY,
176                     [](auto &out) {
177                         out << "return mRemote.unlinkToDeath(recipient);\n";
178                     }
179                 },
180                 {IMPL_STUB, nullptr /* don't generate code */}
181             } /*javaImpl*/
182     );
183     return true;
184 }
fillSyspropsChangedMethod(Method * method) const185 bool Interface::fillSyspropsChangedMethod(Method *method) const {
186     if (method->name() != "notifySyspropsChanged") {
187         return false;
188     }
189 
190     method->fillImplementation(
191             hardware::IBinder::HIDL_SYSPROPS_CHANGED_TRANSACTION,
192             { { IMPL_INTERFACE, [](auto &out) {
193                 out << "::android::report_sysprop_change();\n";
194                 out << "return ::android::hardware::Void();\n";
195             } } }, /*cppImpl */
196             { { IMPL_INTERFACE, [](auto &out) { /* javaImpl */
197                 out << "android.os.HwBinder.enableInstrumentation();\n";
198             } } } /*javaImpl */
199     );
200     return true;
201 }
202 
fillSetHALInstrumentationMethod(Method * method) const203 bool Interface::fillSetHALInstrumentationMethod(Method *method) const {
204     if (method->name() != "setHALInstrumentation") {
205         return false;
206     }
207 
208     method->fillImplementation(
209             hardware::IBinder::HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
210             {
211                 {IMPL_INTERFACE,
212                     [](auto &out) {
213                         // do nothing for base class.
214                         out << "return ::android::hardware::Void();\n";
215                     }
216                 },
217                 {IMPL_STUB,
218                     [](auto &out) {
219                         out << "configureInstrumentation();\n";
220                     }
221                 },
222                 {IMPL_PASSTHROUGH,
223                     [](auto &out) {
224                         out << "configureInstrumentation();\n";
225                         out << "return ::android::hardware::Void();\n";
226                     }
227                 },
228             }, /*cppImpl */
229             { { IMPL_INTERFACE, [](auto & /*out*/) { /* javaImpl */
230                 // Not support for Java Impl for now.
231             } } } /*javaImpl */
232     );
233     return true;
234 }
235 
fillDescriptorChainMethod(Method * method) const236 bool Interface::fillDescriptorChainMethod(Method *method) const {
237     if (method->name() != "interfaceChain") {
238         return false;
239     }
240 
241     method->fillImplementation(
242         hardware::IBinder::HIDL_DESCRIPTOR_CHAIN_TRANSACTION,
243         { { IMPL_INTERFACE, [this](auto &out) {
244             std::vector<const Interface *> chain = typeChain();
245             out << "_hidl_cb(";
246             out.block([&] {
247                 for (const Interface *iface : chain) {
248                     out << iface->fullName() << "::descriptor,\n";
249                 }
250             });
251             out << ");\n";
252             out << "return ::android::hardware::Void();\n";
253         } } }, /* cppImpl */
254         { { IMPL_INTERFACE, [this](auto &out) {
255             std::vector<const Interface *> chain = typeChain();
256             out << "return new java.util.ArrayList<String>(java.util.Arrays.asList(\n";
257             out.indent(); out.indent();
258             for (size_t i = 0; i < chain.size(); ++i) {
259                 if (i != 0)
260                     out << ",\n";
261                 out << chain[i]->fullJavaName() << ".kInterfaceName";
262             }
263             out << "));\n";
264             out.unindent(); out.unindent();
265         } } } /* javaImpl */
266     );
267     return true;
268 }
269 
emitDigestChain(Formatter & out,const std::string & prefix,const std::vector<const Interface * > & chain,std::function<std::string (std::unique_ptr<ConstantExpression>)> byteToString) const270 void Interface::emitDigestChain(
271     Formatter& out, const std::string& prefix, const std::vector<const Interface*>& chain,
272     std::function<std::string(std::unique_ptr<ConstantExpression>)> byteToString) const {
273     out.join(chain.begin(), chain.end(), ",\n", [&](const auto& iface) {
274         out << prefix;
275         out << "{";
276         out.join(
277             iface->getFileHash()->raw().begin(), iface->getFileHash()->raw().end(), ",",
278             [&](const auto& e) {
279                 // Use ConstantExpression::cppValue / javaValue
280                 // because Java used signed byte for uint8_t.
281                 out << byteToString(ConstantExpression::ValueOf(ScalarType::Kind::KIND_UINT8, e));
282             });
283         out << "} /* ";
284         out << iface->getFileHash()->hexString();
285         out << " */";
286     });
287 }
288 
fillHashChainMethod(Method * method) const289 bool Interface::fillHashChainMethod(Method *method) const {
290     if (method->name() != "getHashChain") {
291         return false;
292     }
293     const VectorType *chainType = static_cast<const VectorType *>(&method->results()[0]->type());
294     const ArrayType *digestType = static_cast<const ArrayType *>(chainType->getElementType());
295 
296     method->fillImplementation(
297         hardware::IBinder::HIDL_HASH_CHAIN_TRANSACTION,
298         { { IMPL_INTERFACE, [this, digestType](auto &out) {
299             std::vector<const Interface *> chain = typeChain();
300             out << "_hidl_cb(";
301             out.block([&] {
302                 emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")", chain,
303                                 [](const auto& e) { return e->cppValue(); });
304             });
305             out << ");\n";
306             out << "return ::android::hardware::Void();\n";
307         } } }, /* cppImpl */
308         { { IMPL_INTERFACE, [this, digestType, chainType](auto &out) {
309             std::vector<const Interface *> chain = typeChain();
310             out << "return new "
311                 << chainType->getJavaType(false /* forInitializer */)
312                 << "(java.util.Arrays.asList(\n";
313             out.indent(2, [&] {
314                 // No need for dimensions when elements are explicitly provided.
315                 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
316                                 chain, [](const auto& e) { return e->javaValue(); });
317             });
318             out << "));\n";
319         } } } /* javaImpl */
320     );
321     return true;
322 }
323 
fillGetDescriptorMethod(Method * method) const324 bool Interface::fillGetDescriptorMethod(Method *method) const {
325     if (method->name() != "interfaceDescriptor") {
326         return false;
327     }
328 
329     method->fillImplementation(
330         hardware::IBinder::HIDL_GET_DESCRIPTOR_TRANSACTION,
331         { { IMPL_INTERFACE, [this](auto &out) {
332             out << "_hidl_cb("
333                 << fullName()
334                 << "::descriptor);\n"
335                 << "return ::android::hardware::Void();\n";
336         } } }, /* cppImpl */
337         { { IMPL_INTERFACE, [this](auto &out) {
338             out << "return "
339                 << fullJavaName()
340                 << ".kInterfaceName;\n";
341         } } } /* javaImpl */
342     );
343     return true;
344 }
345 
fillGetDebugInfoMethod(Method * method) const346 bool Interface::fillGetDebugInfoMethod(Method *method) const {
347     if (method->name() != "getDebugInfo") {
348         return false;
349     }
350 
351     static const std::string sArch =
352             "#if defined(__LP64__)\n"
353             "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n"
354             "#else\n"
355             "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n"
356             "#endif\n";
357 
358     method->fillImplementation(
359         hardware::IBinder::HIDL_GET_REF_INFO_TRANSACTION,
360         {
361             {IMPL_INTERFACE,
362                 [](auto &out) {
363                     // getDebugInfo returns N/A for local objects.
364                     out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
365                     out << "info.pid = -1;\n";
366                     out << "info.ptr = 0;\n";
367                     out << "info.arch = \n" << sArch << ";\n";
368                     out << "_hidl_cb(info);\n";
369                     out << "return ::android::hardware::Void();\n";
370                 }
371             },
372             {IMPL_STUB_IMPL,
373                 [](auto &out) {
374                     out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
375                     out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
376                     out << "info.ptr = ::android::hardware::details::debuggable()"
377                         << "? reinterpret_cast<uint64_t>(this) : 0;\n";
378                     out << "info.arch = \n" << sArch << ";\n";
379                     out << "_hidl_cb(info);\n";
380                     out << "return ::android::hardware::Void();\n";
381                 }
382             }
383         }, /* cppImpl */
384         { { IMPL_INTERFACE, [method](auto &out) {
385             const Type &refInfo = method->results().front()->type();
386             out << refInfo.getJavaType(false /* forInitializer */) << " info = new "
387                 << refInfo.getJavaType(true /* forInitializer */) << "();\n"
388                 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n"
389                 << "info.ptr = 0;\n"
390                 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n"
391                 << "return info;\n";
392         } } } /* javaImpl */
393     );
394 
395     return true;
396 }
397 
fillDebugMethod(Method * method) const398 bool Interface::fillDebugMethod(Method *method) const {
399     if (method->name() != "debug") {
400         return false;
401     }
402 
403     method->fillImplementation(hardware::IBinder::HIDL_DEBUG_TRANSACTION,
404                                {
405                                    {IMPL_INTERFACE,
406                                     [](auto& out) {
407                                         out << "(void)fd;\n"
408                                             << "(void)options;\n"
409                                             << "return ::android::hardware::Void();\n";
410                                     }},
411                                }, /* cppImpl */
412                                {
413                                    {IMPL_INTERFACE, [](auto& out) { out << "return;\n"; }},
414                                } /* javaImpl */
415     );
416 
417     return true;
418 }
419 
addUserDefinedMethod(Method * method)420 void Interface::addUserDefinedMethod(Method* method) {
421     CHECK(!method->isHidlReserved());
422     mUserMethods.push_back(method);
423 }
424 
getReferences() const425 std::vector<const Reference<Type>*> Interface::getReferences() const {
426     std::vector<const Reference<Type>*> ret;
427 
428     if (!isIBase()) {
429         ret.push_back(&mSuperType);
430     }
431 
432     for (const auto* method : methods()) {
433         const auto& references = method->getReferences();
434         ret.insert(ret.end(), references.begin(), references.end());
435     }
436 
437     return ret;
438 }
439 
getStrongReferences() const440 std::vector<const Reference<Type>*> Interface::getStrongReferences() const {
441     // Interface is a special case as a reference:
442     // its definiton must be completed for extension but
443     // not necessary for other references.
444 
445     std::vector<const Reference<Type>*> ret;
446     if (!isIBase()) {
447         ret.push_back(&mSuperType);
448     }
449 
450     for (const auto* method : methods()) {
451         const auto& references = method->getStrongReferences();
452         ret.insert(ret.end(), references.begin(), references.end());
453     }
454 
455     return ret;
456 }
457 
resolveInheritance()458 status_t Interface::resolveInheritance() {
459     size_t serial = hardware::IBinder::FIRST_CALL_TRANSACTION;
460     for (const auto* ancestor : superTypeChain()) {
461         serial += ancestor->mUserMethods.size();
462     }
463 
464     for (Method* method : mUserMethods) {
465         if (serial > hardware::IBinder::LAST_CALL_TRANSACTION) {
466             std::cerr << "ERROR: More than " << hardware::IBinder::LAST_CALL_TRANSACTION
467                       << " methods (including super and reserved) are not allowed at " << location()
468                       << std::endl;
469             return UNKNOWN_ERROR;
470         }
471 
472         method->setSerialId(serial);
473         serial++;
474     }
475 
476     return Scope::resolveInheritance();
477 }
478 
validate() const479 status_t Interface::validate() const {
480     CHECK(isIBase() == mSuperType.isEmptyReference());
481 
482     if (!isIBase() && !mSuperType->isInterface()) {
483         std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location()
484                   << std::endl;
485         return UNKNOWN_ERROR;
486     }
487 
488     status_t err;
489 
490     err = validateUniqueNames();
491     if (err != OK) return err;
492 
493     return Scope::validate();
494 }
495 
getAlignmentAndSize(size_t * align,size_t * size) const496 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
497     *align = 8;
498     *size = 8;
499 }
500 
validateUniqueNames() const501 status_t Interface::validateUniqueNames() const {
502     std::unordered_map<std::string, const Interface*> registeredMethodNames;
503     for (auto const& tuple : allSuperMethodsFromRoot()) {
504         // No need to check super method uniqueness
505         registeredMethodNames[tuple.method()->name()] = tuple.interface();
506     }
507 
508     for (const Method* method : mUserMethods) {
509         auto registered = registeredMethodNames.find(method->name());
510 
511         if (registered != registeredMethodNames.end()) {
512             const Interface* definedInType = registered->second;
513 
514             if (definedInType == this) {
515                 // Defined in this interface
516                 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'";
517             } else if (definedInType->isIBase()) {
518                 // Defined in IBase
519                 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'";
520             } else {
521                 // Defined in super not IBase
522                 std::cerr << "ERROR: Redefinition of method '" << method->name()
523                           << "' defined in interface '" << definedInType->fullName() << "'";
524             }
525             std::cerr << " at " << method->location() << std::endl;
526             return UNKNOWN_ERROR;
527         }
528 
529         registeredMethodNames[method->name()] = this;
530     }
531 
532     return OK;
533 }
534 
validateAnnotations() const535 status_t Interface::validateAnnotations() const {
536     for (const Annotation* annotation : annotations()) {
537         const std::string name = annotation->name();
538 
539         if (name == "SensitiveData") {
540             continue;
541         }
542 
543         std::cerr << "WARNING: Unrecognized annotation '" << name << "' for " << typeName()
544                   << " at " << location() << ". Only @SensitiveData is supported." << std::endl;
545         // ideally would be error, but we don't want to break downstream
546         // return UNKNOWN_ERROR;
547     }
548 
549     for (const Method* method : methods()) {
550         for (const Annotation* annotation : method->annotations()) {
551             const std::string name = annotation->name();
552 
553             if (name == "entry" || name == "exit" || name == "callflow") {
554                 continue;
555             }
556 
557             std::cerr << "ERROR: Unrecognized annotation '" << name
558                       << "' for method: " << method->name() << " at " << method->location()
559                       << ". An annotation should be one of: "
560                       << "@entry, @exit, or @callflow." << std::endl;
561             return UNKNOWN_ERROR;
562         }
563     }
564     return OK;  // not calling superclass which is more restrictive
565 }
566 
addAllReservedMethods(const std::map<std::string,Method * > & allReservedMethods)567 bool Interface::addAllReservedMethods(const std::map<std::string, Method*>& allReservedMethods) {
568     // use a sorted map to insert them in serial ID order.
569     std::map<int32_t, Method *> reservedMethodsById;
570     for (const auto& pair : allReservedMethods) {
571         Method *method = pair.second->copySignature();
572         bool fillSuccess = fillPingMethod(method)
573             || fillDescriptorChainMethod(method)
574             || fillGetDescriptorMethod(method)
575             || fillHashChainMethod(method)
576             || fillSyspropsChangedMethod(method)
577             || fillLinkToDeathMethod(method)
578             || fillUnlinkToDeathMethod(method)
579             || fillSetHALInstrumentationMethod(method)
580             || fillGetDebugInfoMethod(method)
581             || fillDebugMethod(method);
582 
583         if (!fillSuccess) {
584             std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name()
585                       << std::endl;
586             return false;
587         }
588         if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
589             std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name()
590                       << " and " << reservedMethodsById[method->getSerialId()]->name()
591                       << ", serialId = " << method->getSerialId() << std::endl;
592             return false;
593         }
594     }
595     for (const auto &pair : reservedMethodsById) {
596         this->mReservedMethods.push_back(pair.second);
597     }
598     return true;
599 }
600 
hasSensitiveDataAnnotation() const601 bool Interface::hasSensitiveDataAnnotation() const {
602     for (const auto& annotation : annotations()) {
603         if (annotation->name() == "SensitiveData") {
604             return true;
605         }
606     }
607 
608     return false;
609 }
610 
superType() const611 const Interface* Interface::superType() const {
612     if (isIBase()) return nullptr;
613     if (!mSuperType->isInterface()) {
614         // This is actually an error
615         // that would be caught in validate
616         return nullptr;
617     }
618     return static_cast<const Interface*>(mSuperType.get());
619 }
620 
typeChain() const621 std::vector<const Interface *> Interface::typeChain() const {
622     std::vector<const Interface *> v;
623     const Interface *iface = this;
624     while (iface != nullptr) {
625         v.push_back(iface);
626         iface = iface->superType();
627     }
628     return v;
629 }
630 
superTypeChain() const631 std::vector<const Interface *> Interface::superTypeChain() const {
632     return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
633 }
634 
isElidableType() const635 bool Interface::isElidableType() const {
636     return true;
637 }
638 
isInterface() const639 bool Interface::isInterface() const {
640     return true;
641 }
642 
userDefinedMethods() const643 const std::vector<Method *> &Interface::userDefinedMethods() const {
644     return mUserMethods;
645 }
646 
hidlReservedMethods() const647 const std::vector<Method *> &Interface::hidlReservedMethods() const {
648     return mReservedMethods;
649 }
650 
methods() const651 std::vector<Method *> Interface::methods() const {
652     std::vector<Method *> v(mUserMethods);
653     v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end());
654     return v;
655 }
656 
allMethodsFromRoot() const657 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const {
658     std::vector<InterfaceAndMethod> v;
659     std::vector<const Interface *> chain = typeChain();
660     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
661         const Interface *iface = *it;
662         for (Method *userMethod : iface->userDefinedMethods()) {
663             v.push_back(InterfaceAndMethod(iface, userMethod));
664         }
665     }
666     for (Method *reservedMethod : hidlReservedMethods()) {
667         v.push_back(InterfaceAndMethod(
668                 *chain.rbegin(), // IBase
669                 reservedMethod));
670     }
671     return v;
672 }
673 
allSuperMethodsFromRoot() const674 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
675     return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
676 }
677 
getBaseName() const678 std::string Interface::getBaseName() const {
679     return fqName().getInterfaceBaseName();
680 }
681 
getAdapterName() const682 std::string Interface::getAdapterName() const {
683     return fqName().getInterfaceAdapterName();
684 }
685 
getProxyName() const686 std::string Interface::getProxyName() const {
687     return fqName().getInterfaceProxyName();
688 }
689 
getStubName() const690 std::string Interface::getStubName() const {
691     return fqName().getInterfaceStubName();
692 }
693 
getHwName() const694 std::string Interface::getHwName() const {
695     return fqName().getInterfaceHwName();
696 }
697 
getPassthroughName() const698 std::string Interface::getPassthroughName() const {
699     return fqName().getInterfacePassthroughName();
700 }
701 
getProxyFqName() const702 FQName Interface::getProxyFqName() const {
703     return fqName().getInterfaceProxyFqName();
704 }
705 
getStubFqName() const706 FQName Interface::getStubFqName() const {
707     return fqName().getInterfaceStubFqName();
708 }
709 
getPassthroughFqName() const710 FQName Interface::getPassthroughFqName() const {
711     return fqName().getInterfacePassthroughFqName();
712 }
713 
getCppType(StorageMode mode,bool specifyNamespaces) const714 std::string Interface::getCppType(StorageMode mode,
715                                   bool specifyNamespaces) const {
716     const std::string base =
717           std::string(specifyNamespaces ? "::android::" : "")
718         + "sp<"
719         + fullName()
720         + ">";
721 
722     switch (mode) {
723         case StorageMode_Stack:
724         case StorageMode_Result:
725             return base;
726 
727         case StorageMode_Argument:
728             return "const " + base + "&";
729     }
730 }
731 
getJavaType(bool) const732 std::string Interface::getJavaType(bool /* forInitializer */) const {
733     return fullJavaName();
734 }
735 
getVtsType() const736 std::string Interface::getVtsType() const {
737     if (StringHelper::EndsWith(definedName(), "Callback")) {
738         return "TYPE_HIDL_CALLBACK";
739     } else {
740         return "TYPE_HIDL_INTERFACE";
741     }
742 }
743 
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const744 void Interface::emitReaderWriter(
745         Formatter &out,
746         const std::string &name,
747         const std::string &parcelObj,
748         bool parcelObjIsPointer,
749         bool isReader,
750         ErrorMode mode) const {
751     const std::string parcelObjDeref =
752         parcelObj + (parcelObjIsPointer ? "->" : ".");
753 
754     if (isReader) {
755         out << "{\n";
756         out.indent();
757 
758         const std::string binderName = "_hidl_binder";
759         out << "::android::sp<::android::hardware::IBinder> "
760             << binderName << ";\n";
761 
762         out << "_hidl_err = ";
763         out << parcelObjDeref
764             << "readNullableStrongBinder(&"
765             << binderName
766             << ");\n";
767 
768         handleError(out, mode);
769 
770         out << name
771             << " = "
772             << "::android::hardware::fromBinder<"
773             << fqName().cppName()
774             << ","
775             << getProxyFqName().cppName()
776             << ","
777             << getStubFqName().cppName()
778             << ">("
779             << binderName
780             << ");\n";
781 
782         out.unindent();
783         out << "}\n\n";
784     } else {
785         out << "if (" << name << " == nullptr) {\n";
786         out.indent();
787         out << "_hidl_err = ";
788         out << parcelObjDeref
789             << "writeStrongBinder(nullptr);\n";
790         out.unindent();
791         out << "} else {\n";
792         out.indent();
793         out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
794             << "::android::hardware::getOrCreateCachedBinder(" << name << ".get());\n";
795         out << "if (_hidl_binder.get() != nullptr) {\n";
796         out.indent([&] {
797             out << "_hidl_err = "
798                 << parcelObjDeref
799                 << "writeStrongBinder(_hidl_binder);\n";
800         });
801         out << "} else {\n";
802         out.indent([&] {
803             out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
804         });
805         out << "}\n";
806         out.unindent();
807         out << "}\n";
808 
809         handleError(out, mode);
810     }
811 }
812 
emitHidlDefinition(Formatter & out) const813 void Interface::emitHidlDefinition(Formatter& out) const {
814     if (getDocComment() != nullptr) getDocComment()->emit(out);
815     out << typeName() << " ";
816 
817     const Interface* super = superType();
818     if (super != nullptr && !super->isIBase()) {
819         out << "extends " << super->fqName().getRelativeFQName(fqName()) << " ";
820     }
821 
822     out << "{";
823 
824     out.indent([&] {
825         const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
826         if (definedTypes.size() > 0 || userDefinedMethods().size() > 0) out << "\n";
827 
828         out.join(definedTypes.begin(), definedTypes.end(), "\n",
829                  [&](auto t) { t->emitHidlDefinition(out); });
830 
831         if (definedTypes.size() > 0 && userDefinedMethods().size() > 0) out << "\n";
832 
833         out.join(userDefinedMethods().begin(), userDefinedMethods().end(), "\n",
834                  [&](auto method) { method->emitHidlDefinition(out); });
835     });
836 
837     out << "};\n";
838 }
839 
emitPackageTypeDeclarations(Formatter & out) const840 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
841     Scope::emitPackageTypeDeclarations(out);
842 
843     out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
844 }
845 
emitPackageTypeHeaderDefinitions(Formatter & out) const846 void Interface::emitPackageTypeHeaderDefinitions(Formatter& out) const {
847     Scope::emitPackageTypeHeaderDefinitions(out);
848 
849     out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
850 
851     out.block([&] {
852         out << "std::string os = \"[class or subclass of \";\n"
853             << "os += " << fullName() << "::descriptor;\n"
854             << "os += \"]\";\n"
855             << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
856             << "return os;\n";
857     }).endl().endl();
858 }
859 
emitTypeDefinitions(Formatter & out,const std::string & prefix) const860 void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
861     std::string space = prefix.empty() ? "" : (prefix + "::");
862 
863     Scope::emitTypeDefinitions(out, space + definedName());
864 }
865 
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const866 void Interface::emitJavaReaderWriter(
867         Formatter &out,
868         const std::string &parcelObj,
869         const std::string &argName,
870         bool isReader) const {
871     if (isReader) {
872         out << fullJavaName()
873             << ".asInterface("
874             << parcelObj
875             << ".readStrongBinder());\n";
876     } else {
877         out << parcelObj
878             << ".writeStrongBinder("
879             << argName
880             << " == null ? null : "
881             << argName
882             << ".asBinder());\n";
883     }
884 }
885 
emitVtsAttributeDeclaration(Formatter & out) const886 void Interface::emitVtsAttributeDeclaration(Formatter& out) const {
887     for (const auto &type : getSubTypes()) {
888         // Skip for TypeDef as it is just an alias of a defined type.
889         if (type->isTypeDef()) {
890             continue;
891         }
892         out << "attribute: {\n";
893         out.indent();
894         type->emitVtsTypeDeclarations(out);
895         out.unindent();
896         out << "}\n\n";
897     }
898 }
899 
emitVtsMethodDeclaration(Formatter & out,bool isInherited) const900 void Interface::emitVtsMethodDeclaration(Formatter& out, bool isInherited) const {
901     for (const auto &method : methods()) {
902         if (method->isHidlReserved()) {
903             continue;
904         }
905 
906         out << "api: {\n";
907         out.indent();
908         out << "name: \"" << method->name() << "\"\n";
909         out << "is_inherited: " << (isInherited ? "true" : "false") << "\n";
910         // Generate declaration for each return value.
911         for (const auto &result : method->results()) {
912             out << "return_type_hidl: {\n";
913             out.indent();
914             out << "name: \"" << result->name() << "\"\n";
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             out << "name: \"" << arg->name() << "\"\n";
924             arg->type().emitVtsAttributeType(out);
925             out.unindent();
926             out << "}\n";
927         }
928         // Generate declaration for each annotation.
929         for (const auto &annotation : method->annotations()) {
930             out << "callflow: {\n";
931             out.indent();
932             const std::string name = annotation->name();
933             if (name == "entry") {
934                 out << "entry: true\n";
935             } else if (name == "exit") {
936                 out << "exit: true\n";
937             } else if (name == "callflow") {
938                 const AnnotationParam *param =
939                         annotation->getParam("next");
940                 if (param != nullptr) {
941                     for (const auto& value : param->getValues()) {
942                         out << "next: " << value << "\n";
943                     }
944                 }
945             } else {
946                 CHECK(false);
947             }
948             out.unindent();
949             out << "}\n";
950         }
951         out.unindent();
952         out << "}\n\n";
953     }
954 }
955 
emitVtsAttributeType(Formatter & out) const956 void Interface::emitVtsAttributeType(Formatter& out) const {
957     out << "type: " << getVtsType() << "\n"
958         << "predefined_type: \""
959         << fullName()
960         << "\"\n";
961 }
962 
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const963 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
964     if (hasSensitiveDataAnnotation()) {
965         return false;
966     }
967 
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 
isNeverStrongReference() const981 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