• 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 <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 " << chainType->getJavaType(false /* forInitializer */);
311             if (chain.size() == 1) {
312                 // https://errorprone.info/bugpattern/ArraysAsListPrimitiveArray
313                 // To avoid an ArraysAsListPrimitiveArray errorprone error, use
314                 // singletonList when there's only 1 element in the chain.
315                 out << "(java.util.Collections.singletonList(\n";
316             } else {
317                 out << "(java.util.Arrays.asList(\n";
318             }
319             out.indent(2, [&] {
320                 // No need for dimensions when elements are explicitly provided.
321                 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
322                                 chain, [](const auto& e) { return e->javaValue(); });
323             });
324             out << "));\n";
325         } } } /* javaImpl */
326     );
327     return true;
328 }
329 
fillGetDescriptorMethod(Method * method) const330 bool Interface::fillGetDescriptorMethod(Method *method) const {
331     if (method->name() != "interfaceDescriptor") {
332         return false;
333     }
334 
335     method->fillImplementation(
336         hardware::IBinder::HIDL_GET_DESCRIPTOR_TRANSACTION,
337         { { IMPL_INTERFACE, [this](auto &out) {
338             out << "_hidl_cb("
339                 << fullName()
340                 << "::descriptor);\n"
341                 << "return ::android::hardware::Void();\n";
342         } } }, /* cppImpl */
343         { { IMPL_INTERFACE, [this](auto &out) {
344             out << "return "
345                 << fullJavaName()
346                 << ".kInterfaceName;\n";
347         } } } /* javaImpl */
348     );
349     return true;
350 }
351 
fillGetDebugInfoMethod(Method * method) const352 bool Interface::fillGetDebugInfoMethod(Method *method) const {
353     if (method->name() != "getDebugInfo") {
354         return false;
355     }
356 
357     static const std::string sArch =
358             "#if defined(__LP64__)\n"
359             "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n"
360             "#else\n"
361             "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n"
362             "#endif\n";
363 
364     method->fillImplementation(
365         hardware::IBinder::HIDL_GET_REF_INFO_TRANSACTION,
366         {
367             {IMPL_INTERFACE,
368                 [](auto &out) {
369                     // getDebugInfo returns N/A for local objects.
370                     out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
371                     out << "info.pid = -1;\n";
372                     out << "info.ptr = 0;\n";
373                     out << "info.arch = \n" << sArch << ";\n";
374                     out << "_hidl_cb(info);\n";
375                     out << "return ::android::hardware::Void();\n";
376                 }
377             },
378             {IMPL_STUB_IMPL,
379                 [](auto &out) {
380                     out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
381                     out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
382                     out << "info.ptr = ::android::hardware::details::debuggable()"
383                         << "? reinterpret_cast<uint64_t>(this) : 0;\n";
384                     out << "info.arch = \n" << sArch << ";\n";
385                     out << "_hidl_cb(info);\n";
386                     out << "return ::android::hardware::Void();\n";
387                 }
388             }
389         }, /* cppImpl */
390         { { IMPL_INTERFACE, [method](auto &out) {
391             const Type &refInfo = method->results().front()->type();
392             out << refInfo.getJavaType(false /* forInitializer */) << " info = new "
393                 << refInfo.getJavaType(true /* forInitializer */) << "();\n"
394                 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n"
395                 << "info.ptr = 0;\n"
396                 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n"
397                 << "return info;\n";
398         } } } /* javaImpl */
399     );
400 
401     return true;
402 }
403 
fillDebugMethod(Method * method) const404 bool Interface::fillDebugMethod(Method *method) const {
405     if (method->name() != "debug") {
406         return false;
407     }
408 
409     method->fillImplementation(hardware::IBinder::HIDL_DEBUG_TRANSACTION,
410                                {
411                                    {IMPL_INTERFACE,
412                                     [](auto& out) {
413                                         out << "(void)fd;\n"
414                                             << "(void)options;\n"
415                                             << "return ::android::hardware::Void();\n";
416                                     }},
417                                }, /* cppImpl */
418                                {
419                                    {IMPL_INTERFACE, [](auto& out) { out << "return;\n"; }},
420                                } /* javaImpl */
421     );
422 
423     return true;
424 }
425 
addUserDefinedMethod(Method * method)426 void Interface::addUserDefinedMethod(Method* method) {
427     CHECK(!method->isHidlReserved());
428     mUserMethods.push_back(method);
429 }
430 
getReferences() const431 std::vector<const Reference<Type>*> Interface::getReferences() const {
432     std::vector<const Reference<Type>*> ret;
433 
434     if (!isIBase()) {
435         ret.push_back(&mSuperType);
436     }
437 
438     for (const auto* method : methods()) {
439         const auto& references = method->getReferences();
440         ret.insert(ret.end(), references.begin(), references.end());
441     }
442 
443     return ret;
444 }
445 
getStrongReferences() const446 std::vector<const Reference<Type>*> Interface::getStrongReferences() const {
447     // Interface is a special case as a reference:
448     // its definiton must be completed for extension but
449     // not necessary for other references.
450 
451     std::vector<const Reference<Type>*> ret;
452     if (!isIBase()) {
453         ret.push_back(&mSuperType);
454     }
455 
456     for (const auto* method : methods()) {
457         const auto& references = method->getStrongReferences();
458         ret.insert(ret.end(), references.begin(), references.end());
459     }
460 
461     return ret;
462 }
463 
resolveInheritance()464 status_t Interface::resolveInheritance() {
465     size_t serial = hardware::IBinder::FIRST_CALL_TRANSACTION;
466     for (const auto* ancestor : superTypeChain()) {
467         serial += ancestor->mUserMethods.size();
468     }
469 
470     for (Method* method : mUserMethods) {
471         if (serial > hardware::IBinder::LAST_CALL_TRANSACTION) {
472             std::cerr << "ERROR: More than " << hardware::IBinder::LAST_CALL_TRANSACTION
473                       << " methods (including super and reserved) are not allowed at " << location()
474                       << std::endl;
475             return UNKNOWN_ERROR;
476         }
477 
478         method->setSerialId(serial);
479         serial++;
480     }
481 
482     return Scope::resolveInheritance();
483 }
484 
validate() const485 status_t Interface::validate() const {
486     CHECK(isIBase() == mSuperType.isEmptyReference());
487 
488     if (!isIBase() && !mSuperType->isInterface()) {
489         std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location()
490                   << std::endl;
491         return UNKNOWN_ERROR;
492     }
493 
494     status_t err;
495 
496     err = validateUniqueNames();
497     if (err != OK) return err;
498 
499     return Scope::validate();
500 }
501 
getAlignmentAndSize(size_t * align,size_t * size) const502 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
503     *align = 8;
504     *size = 8;
505 }
506 
validateUniqueNames() const507 status_t Interface::validateUniqueNames() const {
508     std::unordered_map<std::string, const Interface*> registeredMethodNames;
509     for (auto const& tuple : allSuperMethodsFromRoot()) {
510         // No need to check super method uniqueness
511         registeredMethodNames[tuple.method()->name()] = tuple.interface();
512     }
513 
514     for (const Method* method : mUserMethods) {
515         auto registered = registeredMethodNames.find(method->name());
516 
517         if (registered != registeredMethodNames.end()) {
518             const Interface* definedInType = registered->second;
519 
520             if (definedInType == this) {
521                 // Defined in this interface
522                 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'";
523             } else if (definedInType->isIBase()) {
524                 // Defined in IBase
525                 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'";
526             } else {
527                 // Defined in super not IBase
528                 std::cerr << "ERROR: Redefinition of method '" << method->name()
529                           << "' defined in interface '" << definedInType->fullName() << "'";
530             }
531             std::cerr << " at " << method->location() << std::endl;
532             return UNKNOWN_ERROR;
533         }
534 
535         registeredMethodNames[method->name()] = this;
536     }
537 
538     return OK;
539 }
540 
validateAnnotations() const541 status_t Interface::validateAnnotations() const {
542     for (const Annotation* annotation : annotations()) {
543         const std::string name = annotation->name();
544 
545         if (name == "SensitiveData") {
546             continue;
547         }
548 
549         std::cerr << "WARNING: Unrecognized annotation '" << name << "' for " << typeName()
550                   << " at " << location() << ". Only @SensitiveData is supported." << std::endl;
551         // ideally would be error, but we don't want to break downstream
552         // return UNKNOWN_ERROR;
553     }
554 
555     for (const Method* method : methods()) {
556         for (const Annotation* annotation : method->annotations()) {
557             const std::string name = annotation->name();
558 
559             if (name == "entry" || name == "exit" || name == "callflow") {
560                 continue;
561             }
562 
563             std::cerr << "ERROR: Unrecognized annotation '" << name
564                       << "' for method: " << method->name() << " at " << method->location()
565                       << ". An annotation should be one of: "
566                       << "@entry, @exit, or @callflow." << std::endl;
567             return UNKNOWN_ERROR;
568         }
569     }
570     return OK;  // not calling superclass which is more restrictive
571 }
572 
addAllReservedMethods(const std::map<std::string,Method * > & allReservedMethods)573 bool Interface::addAllReservedMethods(const std::map<std::string, Method*>& allReservedMethods) {
574     // use a sorted map to insert them in serial ID order.
575     std::map<int32_t, Method *> reservedMethodsById;
576     for (const auto& pair : allReservedMethods) {
577         Method *method = pair.second->copySignature();
578         bool fillSuccess = fillPingMethod(method)
579             || fillDescriptorChainMethod(method)
580             || fillGetDescriptorMethod(method)
581             || fillHashChainMethod(method)
582             || fillSyspropsChangedMethod(method)
583             || fillLinkToDeathMethod(method)
584             || fillUnlinkToDeathMethod(method)
585             || fillSetHALInstrumentationMethod(method)
586             || fillGetDebugInfoMethod(method)
587             || fillDebugMethod(method);
588 
589         if (!fillSuccess) {
590             std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name()
591                       << std::endl;
592             return false;
593         }
594         if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
595             std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name()
596                       << " and " << reservedMethodsById[method->getSerialId()]->name()
597                       << ", serialId = " << method->getSerialId() << std::endl;
598             return false;
599         }
600     }
601     for (const auto &pair : reservedMethodsById) {
602         this->mReservedMethods.push_back(pair.second);
603     }
604     return true;
605 }
606 
hasSensitiveDataAnnotation() const607 bool Interface::hasSensitiveDataAnnotation() const {
608     for (const auto& annotation : annotations()) {
609         if (annotation->name() == "SensitiveData") {
610             return true;
611         }
612     }
613 
614     return false;
615 }
616 
superType() const617 const Interface* Interface::superType() const {
618     if (isIBase()) return nullptr;
619     if (!mSuperType->isInterface()) {
620         // This is actually an error
621         // that would be caught in validate
622         return nullptr;
623     }
624     return static_cast<const Interface*>(mSuperType.get());
625 }
626 
typeChain() const627 std::vector<const Interface *> Interface::typeChain() const {
628     std::vector<const Interface *> v;
629     const Interface *iface = this;
630     while (iface != nullptr) {
631         v.push_back(iface);
632         iface = iface->superType();
633     }
634     return v;
635 }
636 
superTypeChain() const637 std::vector<const Interface *> Interface::superTypeChain() const {
638     return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
639 }
640 
isElidableType() const641 bool Interface::isElidableType() const {
642     return true;
643 }
644 
isInterface() const645 bool Interface::isInterface() const {
646     return true;
647 }
648 
userDefinedMethods() const649 const std::vector<Method *> &Interface::userDefinedMethods() const {
650     return mUserMethods;
651 }
652 
hidlReservedMethods() const653 const std::vector<Method *> &Interface::hidlReservedMethods() const {
654     return mReservedMethods;
655 }
656 
methods() const657 std::vector<Method *> Interface::methods() const {
658     std::vector<Method *> v(mUserMethods);
659     v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end());
660     return v;
661 }
662 
allMethodsFromRoot() const663 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const {
664     std::vector<InterfaceAndMethod> v;
665     std::vector<const Interface *> chain = typeChain();
666     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
667         const Interface *iface = *it;
668         for (Method *userMethod : iface->userDefinedMethods()) {
669             v.push_back(InterfaceAndMethod(iface, userMethod));
670         }
671     }
672     for (Method *reservedMethod : hidlReservedMethods()) {
673         v.push_back(InterfaceAndMethod(
674                 *chain.rbegin(), // IBase
675                 reservedMethod));
676     }
677     return v;
678 }
679 
allSuperMethodsFromRoot() const680 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
681     return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
682 }
683 
getBaseName() const684 std::string Interface::getBaseName() const {
685     return fqName().getInterfaceBaseName();
686 }
687 
getProxyName() const688 std::string Interface::getProxyName() const {
689     return fqName().getInterfaceProxyName();
690 }
691 
getStubName() const692 std::string Interface::getStubName() const {
693     return fqName().getInterfaceStubName();
694 }
695 
getHwName() const696 std::string Interface::getHwName() const {
697     return fqName().getInterfaceHwName();
698 }
699 
getPassthroughName() const700 std::string Interface::getPassthroughName() const {
701     return fqName().getInterfacePassthroughName();
702 }
703 
getProxyFqName() const704 FQName Interface::getProxyFqName() const {
705     return fqName().getInterfaceProxyFqName();
706 }
707 
getStubFqName() const708 FQName Interface::getStubFqName() const {
709     return fqName().getInterfaceStubFqName();
710 }
711 
getPassthroughFqName() const712 FQName Interface::getPassthroughFqName() const {
713     return fqName().getInterfacePassthroughFqName();
714 }
715 
getCppType(StorageMode mode,bool specifyNamespaces) const716 std::string Interface::getCppType(StorageMode mode,
717                                   bool specifyNamespaces) const {
718     const std::string base =
719           std::string(specifyNamespaces ? "::android::" : "")
720         + "sp<"
721         + fullName()
722         + ">";
723 
724     switch (mode) {
725         case StorageMode_Stack:
726         case StorageMode_Result:
727             return base;
728 
729         case StorageMode_Argument:
730             return "const " + base + "&";
731     }
732 }
733 
getJavaType(bool) const734 std::string Interface::getJavaType(bool /* forInitializer */) const {
735     return fullJavaName();
736 }
737 
getVtsType() const738 std::string Interface::getVtsType() const {
739     if (StringHelper::EndsWith(definedName(), "Callback")) {
740         return "TYPE_HIDL_CALLBACK";
741     } else {
742         return "TYPE_HIDL_INTERFACE";
743     }
744 }
745 
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const746 void Interface::emitReaderWriter(
747         Formatter &out,
748         const std::string &name,
749         const std::string &parcelObj,
750         bool parcelObjIsPointer,
751         bool isReader,
752         ErrorMode mode) const {
753     const std::string parcelObjDeref =
754         parcelObj + (parcelObjIsPointer ? "->" : ".");
755 
756     if (isReader) {
757         out << "{\n";
758         out.indent();
759 
760         const std::string binderName = "_hidl_binder";
761         out << "::android::sp<::android::hardware::IBinder> "
762             << binderName << ";\n";
763 
764         out << "_hidl_err = ";
765         out << parcelObjDeref
766             << "readNullableStrongBinder(&"
767             << binderName
768             << ");\n";
769 
770         handleError(out, mode);
771 
772         out << name
773             << " = "
774             << "::android::hardware::fromBinder<"
775             << fqName().cppName()
776             << ","
777             << getProxyFqName().cppName()
778             << ","
779             << getStubFqName().cppName()
780             << ">("
781             << binderName
782             << ");\n";
783 
784         out.unindent();
785         out << "}\n\n";
786     } else {
787         out << "if (" << name << " == nullptr) {\n";
788         out.indent();
789         out << "_hidl_err = ";
790         out << parcelObjDeref
791             << "writeStrongBinder(nullptr);\n";
792         out.unindent();
793         out << "} else {\n";
794         out.indent();
795         out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
796             << "::android::hardware::getOrCreateCachedBinder(" << name << ".get());\n";
797         out << "if (_hidl_binder.get() != nullptr) {\n";
798         out.indent([&] {
799             out << "_hidl_err = "
800                 << parcelObjDeref
801                 << "writeStrongBinder(_hidl_binder);\n";
802         });
803         out << "} else {\n";
804         out.indent([&] {
805             out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
806         });
807         out << "}\n";
808         out.unindent();
809         out << "}\n";
810 
811         handleError(out, mode);
812     }
813 }
814 
emitHidlDefinition(Formatter & out) const815 void Interface::emitHidlDefinition(Formatter& out) const {
816     if (getDocComment() != nullptr) getDocComment()->emit(out);
817     out << typeName() << " ";
818 
819     const Interface* super = superType();
820     if (super != nullptr && !super->isIBase()) {
821         out << "extends " << super->fqName().getRelativeFQName(fqName()) << " ";
822     }
823 
824     out << "{";
825 
826     out.indent([&] {
827         const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
828         if (definedTypes.size() > 0 || userDefinedMethods().size() > 0) out << "\n";
829 
830         out.join(definedTypes.begin(), definedTypes.end(), "\n",
831                  [&](auto t) { t->emitHidlDefinition(out); });
832 
833         if (definedTypes.size() > 0 && userDefinedMethods().size() > 0) out << "\n";
834 
835         out.join(userDefinedMethods().begin(), userDefinedMethods().end(), "\n",
836                  [&](auto method) { method->emitHidlDefinition(out); });
837     });
838 
839     out << "};\n";
840 }
841 
emitPackageTypeDeclarations(Formatter & out) const842 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
843     Scope::emitPackageTypeDeclarations(out);
844 
845     out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
846 }
847 
emitPackageTypeHeaderDefinitions(Formatter & out) const848 void Interface::emitPackageTypeHeaderDefinitions(Formatter& out) const {
849     Scope::emitPackageTypeHeaderDefinitions(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 + definedName());
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,bool isInherited) const902 void Interface::emitVtsMethodDeclaration(Formatter& out, bool isInherited) 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         out << "is_inherited: " << (isInherited ? "true" : "false") << "\n";
912         // Generate declaration for each return value.
913         for (const auto &result : method->results()) {
914             out << "return_type_hidl: {\n";
915             out.indent();
916             out << "name: \"" << result->name() << "\"\n";
917             result->type().emitVtsAttributeType(out);
918             out.unindent();
919             out << "}\n";
920         }
921         // Generate declaration for each input argument
922         for (const auto &arg : method->args()) {
923             out << "arg: {\n";
924             out.indent();
925             out << "name: \"" << arg->name() << "\"\n";
926             arg->type().emitVtsAttributeType(out);
927             out.unindent();
928             out << "}\n";
929         }
930         // Generate declaration for each annotation.
931         for (const auto &annotation : method->annotations()) {
932             out << "callflow: {\n";
933             out.indent();
934             const std::string name = annotation->name();
935             if (name == "entry") {
936                 out << "entry: true\n";
937             } else if (name == "exit") {
938                 out << "exit: true\n";
939             } else if (name == "callflow") {
940                 const AnnotationParam *param =
941                         annotation->getParam("next");
942                 if (param != nullptr) {
943                     for (const auto& value : param->getValues()) {
944                         out << "next: " << value << "\n";
945                     }
946                 }
947             } else {
948                 CHECK(false);
949             }
950             out.unindent();
951             out << "}\n";
952         }
953         out.unindent();
954         out << "}\n\n";
955     }
956 }
957 
emitVtsAttributeType(Formatter & out) const958 void Interface::emitVtsAttributeType(Formatter& out) const {
959     out << "type: " << getVtsType() << "\n"
960         << "predefined_type: \""
961         << fullName()
962         << "\"\n";
963 }
964 
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const965 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
966     if (hasSensitiveDataAnnotation()) {
967         return false;
968     }
969 
970     if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
971         return false;
972     }
973 
974     for (const auto* method : methods()) {
975         if (!method->deepIsJavaCompatible(visited)) {
976             return false;
977         }
978     }
979 
980     return Scope::deepIsJavaCompatible(visited);
981 }
982 
isNeverStrongReference() const983 bool Interface::isNeverStrongReference() const {
984     return true;
985 }
986 
987 const FQName gIBaseFqName = FQName("android.hidl.base", "1.0", "IBase");
988 const FQName gIManagerFqName = FQName("android.hidl.manager", "1.0", "IServiceManager");
989 
990 }  // namespace android
991 
992